Расширенное использование
Перераспределение явных типов
Иногда бывает так, что данные хранятся в виде структур (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.