Документация Engee

Расширенное использование

Перераспределение явных типов

Иногда бывает так, что данные хранятся в виде структур (struct), которые вы определили сами или которые определены в каком-либо пакете, но через некоторое время, когда вы хотите загрузить данные, оказывается, что эти структуры изменились.

using JLD2
struct A
    x::Int
end
jldsave("example.jld2"; a = A(42))

В результате, когда вы пытаетесь загрузить файл, появляются предупреждения и даже ошибки, как показано ниже.

julia> using JLD2
julia> struct A{T}
            x::T
       end
julia> load("example.jld2")
┌ Warning: read type A is not a leaf type in workspace; reconstructing
└ @ JLD2 ~/.julia/dev/JLD2/src/data/reconstructing_datatypes.jl:273
Dict{String, Any} with 1 entry:
  "a" => var"##A#257"(42)

Начиная с версии JLD2 v0.4.21 появилось решение этой проблемы. Структура JLDFile содержит словарь typemap, который позволяет явным образом изменять сопоставление типов. Теперь вы можете определить структуру, соответствующую старому определению, и загрузить данные.

julia> struct A_old
            x::Int
        end
julia> f = jldopen("example.jld2","r"; typemap=Dict("Main.A" => A_old))
JLDFile /home/jonas/.julia/dev/JLD2/example.jld2 (read-only)
 └─🔢 a
julia> f["a"]
A_old(42)

Обновление старых структур при загрузке

В предыдущем разделе объяснялось, как в JLD2 можно настроить загрузку старых структур с другим целевым именем типа данных. Здесь же описывается другой способ загрузки старых данных:

# Это старая версия структуры, хранящейся в файле
struct OldStructVersion
    x::Int
    y::Float64
end
orig = OldStructVersion(1,2.0)
jldsave("test.jld2"; data=orig)

### новый сеанс

# Это новая версия структуры
struct UpdatedStruct
    x::Float64 # больше не int
    y::Float64
    z::Float64 # = x*y
end

# При обновлении структуры JLD2 загружает поля старой структуры в кортеж `NamedTuple`
# и вызывает для него `rconvert`. Здесь реализуется метод преобразования, возвращающий `UpdatedStruct`
JLD2.rconvert(::Type{UpdatedStruct}, nt::NamedTuple) = UpdatedStruct(Float64(nt.x), nt.y, nt.x*nt.y)

# Здесь предоставляется именованный аргумент `typemap`. Это словарь, сопоставляющий имя хранящейся структуры
# с экземпляром `Upgrade` с новой структурой.
load("test.jld2", "data"; typemap=Dict("Main.OldStructVersion" => JLD2.Upgrade(UpdatedStruct)))

Группы — добавление к файлам

Объекты групп можно создавать с двумя необязательными именованными аргументами:

g = Group(file;
          est_num_entries=4
          est_link_name_len=8)

Они определяют, сколько (дополнительного) пустого пространства следует выделить для описания группы (списка записей). Это может быть полезно с точки зрения производительности, если после первоначальной записи в файл в него планируется добавлять много дополнительных наборов данных.

JLD2DebugTools

В отладке файлов может помочь экспериментальный репозиторий JLD2DebugTools.jl.

Резервный вариант

По умолчанию JLD2 пытается открывать файлы с использованием модуля MmapIO. Если сделать это не удается, выполняется повторная попытка с использованием IOStream.