4

What is the most idiomatic way to write a data structure to disk in Clojure, so I can read it back with edn/read? I tried the following, as recommended in the Clojure cookbook:

(with-open [w (clojure.java.io/writer "data.clj")]
  (binding [*out* w]
    (pr large-data-structure)))

However, this will only write the first 100 items, followed by "...". I tried (prn (doall large-data-structure)) as well, yielding the same result.

I've managed to do it by writing line by line with (doseq [i large-data-structure] (pr i)), but then I have to manually add the parens at the beginning and end of the sequence to get the desired result.

pholz
  • 684
  • 8
  • 19

1 Answers1

4

You can control the number of items in a collection that are printed via *print-length*

Consider using spit instead of manually opening the writer and pr-str instead of manually binding to *out*.

(binding [*print-length* false]
  (spit "data.clj" (pr-str large-data-structure))

Edit from comment:

(with-open [w (clojure.java.io/writer "data.clj")]
  (binding [*print-length* false
            *out* w]
    (pr large-data-structure)))

Note: *print-length* has a root binding of nil so you should not need to bind it in the example above. I would check the current binding at the time of your original pr call.

Kyle
  • 21,978
  • 2
  • 60
  • 61
  • 1
    Using `(pr-str)` is a bad idea for a large data structure; it will print it to a string in memory, which may take more memory than the original structure. I would simply add the `*print-length*` nil binding to the binding vector in OP's code. – Diego Basch Nov 21 '14 at 15:19
  • 1
    My `*print-length*` was set to 100. The culprit seems to be emacs live. See http://stackoverflow.com/questions/20300594/clojure-pr-str-cutting-off-lists-100-items – pholz Nov 21 '14 at 15:22