11
votes

The task is to save and load a HashDict of structs to and from a file, using Elixir. I was planning on iterating over the HashDict and writing out a struct on each line of the file. However, I was unable to find anything on Google on how to save a Struct or Dict to a file. In particular, is there a built-in way of serialising Dicts?

I tried converting to a string first. The iex snippet:-

iex(68)> {:ok,of} = File.open("ztest.txt", [:write, :utf8])
{:ok, #PID<0.232.0>}
iex(69)> IO.write(of, {:atuple, "abc"})                    
** (Protocol.UndefinedError) protocol String.Chars not implemented for {:atuple, "abc"}

One wonders how to make an implementation of String.chars for a map or a tuple?

Also, is it possible to pipe the output of IO.inspect into a file? My attempts to do this were unsuccessful.

1
And found how to save IO.inspect output to a string. An example: IO.puts "Write an atom in a list to string: #{inspect [:abc, 1]}"steve77

1 Answers

29
votes

You can use :erlang.term_to_binary and :erlang.binary_to_term to serialized and deserialize your HashDict:

iex> dict = HashDict.new |> Dict.put(:struct1, %{some: :struct})
#HashDict<[struct1: %{some: :struct}]>
iex> File.write! "encoded.txt", :erlang.term_to_binary(dict)
:ok
iex> File.read!("encoded.txt") |> :erlang.binary_to_term
#HashDict<[struct1: %{some: :struct}]>