gpt4 book ai didi

clojure - 我如何从文件中反序列化记录结构,已经使用 print-dup 保存到文件中?

转载 作者:行者123 更新时间:2023-12-02 04:50:27 25 4
gpt4 key购买 nike

我有以下代码:

(use 'clojure.java.io)
(defrecord Member [id name salary role])
(defrecord Role [id name])
(def member-records (ref ()))
(defn add-member [member]
(dosync (alter member-records conj member)))

;;Test-data -->
(def dev-r(->Role 1 "Developer"))
(def test-member1(->Member 1 "Kirill" 70000.00 dev-r))
;;Test-data <--

(defn save-data-2-file []
(with-open [wrtr (writer "C:/Platform/Work/test.cdf")]
(print-dup @member-records wrtr)))

(defn process-line [line]
(println line))

;;Test line content
;;#BTC.pcost.Member{:id 1, :name "Kirill", :salary 70000.0, :role #BTC.pcost.Role{:id 1, :name "Developer"}})

(defn load-data-from-file []
(with-open [rdr (reader "C:/Platform/Work/test.cdf")]
(doseq [line (line-seq rdr)]
(process-line line))))

我想在读取文件后重新创建记录,但我不明白我该怎么做。是的,我知道我可以解析文本并通过解析行的元素填充我的结构,但这会很困难,因为我有很多结构,如“成员”和“角色”。任何人都可以建议我一个我可以做的方法吗?

最佳答案

您可以使用 read-string , 和 slurp , 将记录从文件中拉出。 read-string仅限于读取字符串的第一种形式,但是,从您的示例中,您只存储一种形式,作为记录列表。

(defn load-data-from-file [file]
(read-string (slurp file)))


懒惰阅读

如果你需要的不仅仅是第一种形式,或者无法将整个流读入内存,你可以使用read直接,让读者懒惰。

(defn lazy-read
([rdr] (let [eof (Object.)] (lazy-read rdr (read rdr false eof) eof)))
([rdr data eof]
(if (not= eof data)
(cons data (lazy-seq (lazy-read rdr (read rdr false eof) eof))))))

(defn load-all-data [file]
(with-open [rdr (java.io.PushbackReader. (reader file))]
(doall (lazy-read rdr))))

(load-all-data "C:/Platform/Work/test.cdf")


安全

此外,在使用 read-string 加载代码时最好提及安全性或 read .您应该只将它们与可信来源 一起使用,因为使用#= 或 Java 构造函数,来源可以在您的应用程序中执行任意代码。如需更长的解释,请查看 read 的文档.

设置*read-eval*false 可以防止出现此问题,但它也会阻止重建样本中的记录。为了一起避免这个问题,您可以使用 clojure.edn/readclojure.edn/read-string函数,带有读者白名单。

(defn edn-read [eof rdr]
(clojure.edn/read {:eof eof :readers {'BTC.pcost.Role map->Role
'BTC.pcost.Member map->Member}}
rdr))

(defn lazy-edn-read
([rdr] (let [eof (Object.)] (lazy-edn-read rdr (edn-read eof rdr) eof)))
([rdr data eof]
(if (not= eof data)
(cons data (lazy-seq (lazy-edn-read rdr (edn-read eof rdr) eof))))))

(defn load-all-data [file]
(with-open [rdr (java.io.PushbackReader. (reader file))]
(doall (take-while (complement nil?) (lazy-edn-read rdr)))))

(load-all-data "C:/Platform/Work/test.cdf")

关于clojure - 我如何从文件中反序列化记录结构,已经使用 print-dup 保存到文件中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18946979/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com