nha
nha

Reputation: 18005

Clojure spit behaviour on byte arrays

The following code :

(spit "/Users/nha/tmp/spit.txt" (.getBytes "hello"))

produces a file containing "[B@71e054bc", which is independent of the content ("hello" in this case) since this is the JVM representation of the address of a byte array.

However the following works (taken from this SO post):

  (clojure.java.io/copy
   (.getBytes "hello")
   (java.io.File. "/Users/nha/tmp/spit.txt"))

And the file then contains the correct content "hello".

Why does spit behave like this ? Is there a way to expand it's behaviour for bytes ?

Upvotes: 3

Views: 1517

Answers (2)

birdspider
birdspider

Reputation: 3074

the reason is that the content is passed to str

you can check that via (source spit):

user=> (source spit)
(defn spit
  "Opposite of slurp.  Opens f with writer, writes content, then
  closes f. Options passed to clojure.java.io/writer."
  {:added "1.2"}
  [f content & options]
  (with-open [^java.io.Writer w (apply jio/writer f options)]
    (.write w (str content))))
;            - ^^^ - here

therefor you get the string representation of the byte-array written

EDIT: and since spit the "inverse" of slurp which gives you a string, it makes sense and is consistent behaviour

Upvotes: 3

glts
glts

Reputation: 22684

This problem isn’t particular to byte arrays.

(spit "spit.txt" (Object.))
(slurp "spit.txt")              ;; => "java.lang.Object@90b293d"

Looking at the source of spit you’ll see that it simply tries to obtain the string representation of the argument before writing it out.

You could try to wrap any byte array in a new string before writing, but take care to select the proper encoding.

;; platform-dependent!
(spit "spit.txt" (String. b))

;; better
(spit "spit.txt" (String. b java.nio.charset.StandardCharsets/UTF_8))

Upvotes: 3

Related Questions