Hi Mike,

On Thu, Jul 9, 2009 at 12:10 PM, Mike<cki...@gmail.com> wrote:
>
> I wanted to grab bytes out of a stream, and didn't see an analogue to
> reader from duck-streams, so I made my own:
>
> (defn byte-seq
>  "Returns the bytes from stream as a lazy sequence of ints.
>  stream must implement java.io.InputStream."
>  [#^java.io.InputStream stream]
>  (lazy-seq
>   (let [b  (. stream (read))]
>     (if (>= b 0)
>       (cons b (byte-seq stream))))))
>
> Then I did a simple lazy operation on a stream of bytes, say, to drop
> the first 5:
>
> (with-open [st (FileInputStream. "mike.clj")] (drop 5 (byte-seq st)))
>
> I was a little surprised at first getting java.io.IOException: Bad
> file descriptor, but of course it hit me:  the laziness persists well
> beyond the .close() in the with-open.
>
> I modified my byte-seq to close the stream when EOF is reached, but
> this is an awful ugly solution having the inner thing know when to
> close the outer concern's thing.  (What if the outer thing wants to
> rewind?  etc.)
>
> Is there a pattern out there in Clojure for handling laziness at the
> same time as handling resource lifecycle (with-open, etc.)?

I think you have two ways to deal with this: (1) Include all your
processing inside the with-open body, or (2) realize the seq by
calling doall.
With (1) you can take advantage of the laziness by using only the
parts of the seq you really need, but you have to have all your
processing in there which may seem a bit messy when there is a lot of
processing code.
With (2) you can return the complete seq for processing in other
places, so you can encapsulate the reading in a function, but you have
all the data in memory.

You could also combine these approaches, by doing some preprocessing
(like dropping 5 elements) and then returning the realized result seq.
(with-open [st (FileInputStream. "msghub.clj")] (doall (drop 5 (byte-seq st))))

I hope this helps
Janico

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to