Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 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?

like image 516
pauldoo Avatar asked Jul 07 '11 15:07

pauldoo


1 Answers

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.

like image 187
Sean Corfield Avatar answered Sep 28 '22 13:09

Sean Corfield