Using `line-seq` with `reader`, when is the file closed?
I'm reading lines from a text file using (line-seq (reader "input.txt"))
. This collection is then passed around and used by my program.
I'm concerned that this may be bad style however, as 开发者_Go百科I'm not deterministically closing the file. I imagine that I can't use (with-open (line-seq (reader "input.txt")))
, as the file stream will potentially get closed before I've traversed the entire sequence.
Should lazy-seq
be avoided in conjunction with reader
for files? Is there a different pattern I should be using here?
Since this doesn't really have a clear answer (it's all mixed into comments on the first answer), here's the essence of it:
(with-open [r (reader "input.txt")]
(doall (line-seq r)))
That will force the whole sequence of lines to be read and close the file. You can then pass the result of that whole expression around.
When dealing with large files, you may have memory problems (holding the whole sequence of lines in memory) and that's when it's a good idea to invert the program:
(with-open [r (reader "input.txt")]
(doall (my-program (line-seq r))))
You may or may not need doall in that case, depending on what my-program returns and/or whether my-program consumes the sequence lazily or not.
It seems like the clojure.contrib.duck-streams/read-lines is just what you are looking for. read-lines
closes the file when there is no input and returns the sequence just like line-seq
. Try to look at source code of read-lines
.
精彩评论