# How to save and read a structure?

**URL:** <https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031>\
**Category:** General Usage\
**Tags:** question, struct, io\
**Created:** [November 5, 2021, 10:54pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031 "2021-11-05T22:54:10Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [November 5, 2021, 10:54pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/1 "2021-11-05T22:54:10Z")

</div>

I am trying to save my designed structure into a file. However, when I am trying to read it, its structure seems to be lost. Any idea how to maintain its structure and do it correctly?

```julia
using FileIO, JLD
mutable struct S
    id::Vector{String}
    value::Vector{Float64}
end
CP=S[];
push!(CP, S(["3d4f7006", "3d4f7006"], [2.0,3.0]));
push!(CP, S(["3d5ce1ef", "3d5ce1ef"], [7.0,8.0]));
save("SavedObjects.jld", "CP",CP)
save("SavedObjects.jld", "CP",CP])

#####
d = load("SavedObjects.jld")
┌ Warning: type S not present in workspace; interpreting array as Array{Any}
└ @ JLD C:\Users\amroa\.julia\packages\JLD\JHrZe\src\JLD.jl:514
┌ Warning: type S not present in workspace; reconstructing
└ @ JLD C:\Users\amroa\.julia\packages\JLD\JHrZe\src\jld_types.jl:697
Dict{String, Any} with 1 entry:
  "CP" => Any[var"##S#257"(["3d4f7006", "3d4f7006"], [2.0, 3.0]), var"##S#257"(["3d5ce1ef", "3d5ce1ef"], [7.0, 8.0])]

julia> d[2].id[1] # here I expect to return "3d5ce1ef"
ERROR: KeyError: key 2 not found
Stacktrace:
 [1] getindex(h::Dict{String, Any}, key::Int64)
   @ Base .\dict.jl:482
 [2] top-level scope
   @ REPL[3]:1

```

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [November 6, 2021, 12:31am UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/2 "2021-11-06T00:31:01Z")

</div>

JLD is at best in maintenance mode these days, AIUI. Have you tried using [GitHub - JuliaIO/JLD2.jl: HDF5-compatible file format in pure Julia](https://github.com/JuliaIO/JLD2.jl)?

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [November 6, 2021, 8:19am UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/3 "2021-11-06T08:19:16Z")

</div>

[Serialization · The Julia Language](https://docs.julialang.org/en/v1/stdlib/Serialization/) is a simple built in option.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [November 6, 2021, 10:23am UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/4 "2021-11-06T10:23:50Z")

</div>

I have been using `JSON3.jl` for that. It works.

---

<div class="post-metadata">

**Author:** ![hendri54](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hendri54/32/9621_2.png) [@hendri54](https://discourse.julialang.org/u/hendri54)\
**Post date:** [November 6, 2021, 6:15pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/5 "2021-11-06T18:15:35Z")

</div>

I have tried various packages for this purpose. In the end, JLD2 works best for me. It works most of the time. But sometimes a set of files ends up unreadable later on (I don’t know why).  
My rule is therefore: I use JLD2 for convenience. But when I cannot lose something, I write it to a text file using JSON3.  
One point to note: when the file is read, the `struct` to be reconstructed needs to be accessible in `Main`; otherwise a reconstructed object is constructed instead (which has the same fields as the original one). (The last point is from the JLD2 documentation from some time ago; please correct me if this is no longer true).

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [November 8, 2021, 3:08pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/6 "2021-11-08T15:08:41Z")

</div>

@lmiq  
I have read the documentation but it seems, I am not doing it correctly. In may my example, I am doing the following but I am having errors:

In the writing file:

```julia
using StructTypes, JSON3
mutable struct S
    id::Vector{String}
    value::Vector{Float64}
end
CP=S[];
push!(CP, S(["3d4f7006", "3d4f7006"], [2.0,3.0]));
push!(CP, S(["3d5ce1ef", "3d5ce1ef"], [7.0,8.0]));
StructTypes.StructType(::Type{S}) = StructTypes.Mutable()
open("My_file.json", "w") do io
    JSON3.write(io, CP)
end

```

In the reading file:

```julia
using StructTypes, JSON3
mutable struct S
    id::Vector{String}
    value::Vector{Float64}
end
StructTypes.StructType(::Type{S}) = StructTypes.Mutable()
CP = JSON3.read("My_file.json", S; kw...)

```

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [November 8, 2021, 3:17pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/7 "2021-11-08T15:17:13Z")

</div>

@ToucheSir @hendri54 I wrote as below, but it gave me error:

```julia
 using FileIO, JLD2
mutable struct S
    id::Vector{String}
    value::Vector{Float64}
end
CP=S[];
push!(CP, S(["3d4f7006", "3d4f7006"], [2.0,3.0]));
push!(CP, S(["3d5ce1ef", "3d5ce1ef"], [7.0,8.0]));
save("My_file.jld2", "CP",CP)
ERROR: LoadError: too many parameters for type
Stacktrace:

```

---

<div class="post-metadata">

**Author:** ![albheim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albheim/32/34660_2.png) [@albheim](https://discourse.julialang.org/u/albheim)\
**Post date:** [November 8, 2021, 3:28pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/8 "2021-11-08T15:28:46Z")

</div>

This code does not error for me on julia 1.6.3

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [November 8, 2021, 3:37pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/9 "2021-11-08T15:37:19Z")

</div>

@albheim  
I see, I am using VS code with julia v1.4.3

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [November 8, 2021, 3:47pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/10 "2021-11-08T15:47:27Z")

</div>

I use this:

```julia
using StructTypes
using JSON3

StructTypes.StructType(::Type{SolSummary}) = StructTypes.Struct()
StructTypes.StructType(::Type{MutableResult}) = StructTypes.Struct()
StructTypes.StructType(::Type{Result}) = StructTypes.Struct()
StructTypes.StructType(::Type{Density}) = StructTypes.Struct()
StructTypes.StructType(::Type{Volume}) = StructTypes.Struct()
StructTypes.StructType(::Type{Options}) = StructTypes.Struct()

function save(R::Result, filename::String)
  f = open(filename,"w")
  JSON3.write(f,R)
  close(f)
end

```

My function to load the struct has a complication, because you cannot save multidimensional arrays in JSON3:

```julia
unction load(filename::String)
  f = open(filename,"r")
  R = JSON3.read(f,MutableResult)
  # Need to reshape the solute and solvent atom contributions, because
  # the data is read in a single column
  solute_atom = reshape(R.solute_atom,R.nbins,:)
  solvent_atom = reshape(R.solvent_atom,R.nbins,:)
  R.solute_atom = solute_atom
  R.solvent_atom = solvent_atom
  return Result([getfield(R,field) for field in fieldnames(Result)]...)
end

```

I cannot say much more, I only followed instructions until that worked out.

---

<div class="post-metadata">

**Author:** ![albheim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albheim/32/34660_2.png) [@albheim](https://discourse.julialang.org/u/albheim)\
**Post date:** [November 8, 2021, 3:48pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/11 "2021-11-08T15:48:02Z")

</div>

Hmm, I think 1.4.2 is the last version in the 1.4 series. I tested with 1.4.2 and it seemed to work without errors there too.

I think you have something else going on in your environment.

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [November 8, 2021, 4:13pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/12 "2021-11-08T16:13:12Z")

</div>

Thanks for your reply. I tried to do the following, is it correct?

```julia
mutable struct S
    id::Vector{String}
    value::Vector{Float64}
end
CP=S[];
push!(CP, S(["3d4f7006", "3d4f7006"], [2.0,3.0]));
push!(CP, S(["3d5ce1ef", "3d5ce1ef"], [7.0,8.0]));
StructTypes.StructType(::Type{SolSummary}) = StructTypes.Struct()
StructTypes.StructType(::Type{MutableResult}) = StructTypes.Struct()
StructTypes.StructType(::Type{Result}) = StructTypes.Struct()
StructTypes.StructType(::Type{Density}) = StructTypes.Struct()
StructTypes.StructType(::Type{Volume}) = StructTypes.Struct()
StructTypes.StructType(::Type{Options}) = StructTypes.Struct()
function save(R::Result, filename::String)
    f = open(filename,"w")
    JSON3.write(f,R)
    close(f)
end
save(CP, "SavedObjectsJ.json")
ERROR: LoadError: UndefVarError: SolSummary not defined
Stacktrace:

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [November 8, 2021, 4:23pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/13 "2021-11-08T16:23:09Z")

</div>

No, `SolSummary`and the other names are the names of the `structs` I have in my code.

Ah, but I noticed now that you want to save a vector of structs, each of which has vectors as fields… I think that won’t work using JSON3 without a bit of tinkering.

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [November 8, 2021, 4:35pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/14 "2021-11-08T16:35:25Z")

</div>

@leandromartinez98 Yeah, a vector of structs

```julia
mutable struct S
    id::Vector{String}
    value::Vector{Float64}
end
CP=S[];
push!(CP, S(["3d4f7006", "3d4f7006"], [2.0,3.0]));
push!(CP, S(["3d5ce1ef", "3d5ce1ef"], [7.0,8.0]));
StructTypes.StructType(::Type{S}) = StructTypes.Mutable()
function save(R::S, filename::String)
    f = open(filename,"w")
    JSON3.write(f,R)
    close(f)
end
save(CP, "My_file.json")
ERROR: LoadError: MethodError: no method matching save(::Vector{S}, ::String)
Closest candidates are:

```

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [November 8, 2021, 5:08pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/15 "2021-11-08T17:08:28Z")

</div>

@albheim does it read the structure correctly when you read it?

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [November 8, 2021, 5:50pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/16 "2021-11-08T17:50:57Z")

</div>

@lmiq do you think in my case, there would be a more suitable package?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [November 8, 2021, 6:09pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/17 "2021-11-08T18:09:57Z")

</div>

Not that I know of. If it was me I would be writing a custom function. But I’m not an expert on those things.

---

<div class="post-metadata">

**Author:** ![Amro](https://avatars.discourse-cdn.com/v4/letter/a/4491bb/32.png) [@Amro](https://discourse.julialang.org/u/Amro)\
**Post date:** [November 8, 2021, 7:12pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/18 "2021-11-08T19:12:23Z")

</div>

Ok, thank you very much!

---

<div class="post-metadata">

**Author:** ![albheim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albheim/32/34660_2.png) [@albheim](https://discourse.julialang.org/u/albheim)\
**Post date:** [November 8, 2021, 9:56pm UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/19 "2021-11-08T21:56:02Z")

</div>

Never tried that, only checked for the error you mentioned. On another computer now, but can check tomorrow if I remember.

---

<div class="post-metadata">

**Author:** ![Perrin\_Meyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/perrin_meyer/32/15686_2.png) [@Perrin\_Meyer](https://discourse.julialang.org/u/Perrin_Meyer)\
**Post date:** [November 9, 2021, 1:30am UTC](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031/20 "2021-11-09T01:30:50Z")

</div>

I’ve had good luck with BSON.jl (binary JSON), worth a look?

[Next page](https://discourse.julialang.org/t/how-to-save-and-read-a-structure/71031.md?page=2)
