taoensso / nippy

The fastest serialization library for Clojure
https://www.taoensso.com/nippy
Eclipse Public License 1.0
1.04k stars 60 forks source link

Question: "right" way to thaw an input-stream #97

Closed martinklepsch closed 7 years ago

martinklepsch commented 7 years ago

Hey! Let's say I have an input stream like this:

(:input-stream (s3/get-object bucket "some-thing"))

What would be the right way to thaw it? I tried converting the input-stream to a DataInputStream (and using thaw-from-in! but that resulted in failed deserializtion:

ExceptionInfo Unrecognized type id (78). Data frozen with newer Nippy version?  

I ended up doing something like below involving commons' IOUtils class:

(-> (s3/get-object bucket "some-thing")
      :input-stream
      IOUtils/toByteArray
      nippy/thaw)

Maybe this would be something useful for the readme or this issue will be helpful to others.

DerGuteMoritz commented 7 years ago

Here's a concise repro case:

(-> (nippy/freeze [:hello 123])
    (java.io.ByteArrayInputStream.)
    (java.io.DataInputStream.)
    (nippy/thaw-from-in!))
DerGuteMoritz commented 7 years ago

Going through freeze-to-out! works, though:

(let [out (java.io.ByteArrayOutputStream.)]
  (nippy/freeze-to-out! (java.io.DataOutputStream. out) [:hello 123])
  (-> (.toByteArray out)
      (java.io.ByteArrayInputStream.)
      (java.io.DataInputStream.)
      (nippy/thaw-from-in!)))
;; => [:hello 123]
ptaoussanis commented 7 years ago

Hey Martin, Moritz-

So as the docstrings mention, thaw-from-in! and freeze-to-out! are low-level utils.

Specifically:

So you can't mix freeze-to-out! with thaw or thaw-from-in! with freeze.

Going through freeze-to-out! works, though

So long as you consistently use the low/high level utils for freezing + thawing you'll be fine.

Does that help / make sense?

martinklepsch commented 7 years ago

Ah that's really good to know, I was absolutely unaware that thaw/freeze and their low level counterparts are not directly compatible. 😅 Thanks for clearing that up :)

So with regards to the original question this means that it should have worked if I

Correct?

ptaoussanis commented 7 years ago

I was absolutely unaware that thaw/freeze and their low level counterparts are not directly compatible

It's an intrinsic incompatibility; the regular thaw/freeze support encryption + compression, but those require[1] the whole byte-array to be available up-front.

Correct?

Sounds good 👍

[1] Technically we could try do streaming encryption+compression, but that has its own tradeoffs - including limiting the encryption+compression options.

martinklepsch commented 7 years ago

Thanks for all the explanations :)