Writing clojure maps/arrays to a file and reading them back

后端 未结 3 957
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-13 18:05

I need to save clojure maps to a file and read them back later to process them.

This is what I could come up with. Is there a better way to accomplish the same thing?

相关标签:
3条回答
  • 2021-02-13 18:24

    It is easiest to read a single form to and from the file, so I usually put my data into a vector. I also prefer to use pr or pr-str rather than print because it is guaranteed to produce readable data,

    (def my-data [{:a "foo" :b [1 2 3]} "asdf" 42 #{1 2 3}]) 
    (spit "/tmp/data.edn" (with-out-str (pr my-data)))
    nil
    (read-string (slurp "/tmp/data.edn"))
    [{:a "foo", :b [1 2 3]} "asdf" 42 #{1 2 3}] 
    

    vs:

    (spit "/tmp/data.edn" (with-out-str (print my-data)))
    (read-string (slurp "/tmp/data.edn"))
    [{:a foo, :b [1 2 3]} asdf 42 #{1 2 3}] 
    

    notice how the string `"asdf" was read back as a symbol.

    .toString also works fine:

    (spit "/tmp/data.edn" (.toString my-data)) 
    (read-string (slurp "/tmp/data.edn"))
    [{:a "foo", :b [1 2 3]} "asdf" 42 #{1 2 3}] 
    
    0 讨论(0)
  • 2021-02-13 18:34

    Yes - spit and prn-str for writing, slurp and read-string for reading.

    user=> (def a [1 2 3 4])
    #'user/a
    user=> (prn-str a)
    "[1 2 3 4]\n"
    user=> (spit "stored-array.dat" (prn-str a))
    nil
    

    (in a new REPL session)

    user=> (require 'clojure.edn)
    nil
    user=> (slurp "stored-array.dat")
    "[1 2 3 4]\n"
    user=> (clojure.edn/read-string (slurp "stored-array.dat"))
    [1 2 3 4]
    

    I used a vector for that example, but any data (e.g. maps) should work just as well.

    Note that there is a read-string in the main Clojure language, but this is explicitly documented as not being safe for untrusted data, so it's better to use the version from clojure.edn.

    0 讨论(0)
  • 2021-02-13 18:35

    Take a look at this question that deals with print-dup and serializing forms. It has a better coverage of the trade-offs and security issues involved with each method.

    0 讨论(0)
提交回复
热议问题