将clojure贴图/数组写入文件并将其读回

psa*_*dhi 11 file-io clojure

我需要将clojure贴图保存到文件中,稍后再读回来处理它们.

这就是我能想到的.有没有更好的方法来完成同样的事情?

user=> (def my-data (for [ a [ "Person1" "Person2" ]  b [ "Address1" "Address2"]  c   (range 10) ] {:name a :address b :index c} ))
#'user/my-data
user=> (count my-data)
40

user=> (defn write-data[xs] (with-open [wrtr (clojure.java.io/writer "my-data.txt") ]
              (doall (map #(.write wrtr (str % "\n")) xs))))
#'user/write-data

user=> (write-data my-data)

user=> (defn read-data[] (with-open [rdr (clojure.java.io/reader "my-data.txt") ]
            (doall (map #(load-string %) (line-seq rdr)))))
#'user/read-data

user=> (count (read-data))
40
Run Code Online (Sandbox Code Playgroud)

Art*_*ldt 14

从文件中读取单个表单最简单,因此我通常将数据放入向量中.我也更喜欢使用pr pr-str而不是print,因为它可以保证产生可读数据,

(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}] 
Run Code Online (Sandbox Code Playgroud)

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}] 
Run Code Online (Sandbox Code Playgroud)

注意字符串`"asdf"是如何作为符号回读的.

.toString 也工作正常:

(spit "/tmp/data.edn" (.toString my-data)) 
(read-string (slurp "/tmp/data.edn"))
[{:a "foo", :b [1 2 3]} "asdf" 42 #{1 2 3}] 
Run Code Online (Sandbox Code Playgroud)

  • 已经有一个函数`clojure.core/pr-str`可以执行`(with-out-str(pr x))`. (3认同)

rkd*_*day 11

是- spitprn-str写作,slurpread-string阅读.

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
Run Code Online (Sandbox Code Playgroud)

(在新的REPL会议中)

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]
Run Code Online (Sandbox Code Playgroud)

我在这个例子中使用了一个向量,但是任何数据(例如地图)都应该可以正常工作.

请注意,主Clojure语言中有一个读取字符串,但明确记录为对不受信任的数据不安全,因此最好使用clojure.edn中的版本.