I need to create an iterator using Source.getLines(), and from a quick look at the Scala source code, and after running some tests it seems like the iterator does not close even after the iterator is exhausted (i.e., after hasNext() begins to be false).
I'm wondering what is Scala's recommended technique for closing/releasing resources used to create an iterator. I found an interesting library that seems like it would do the trick:
https://github.com/jsuereth/scala-arm
However, I'd prefer to use core scala libraries instead of pulling in 3rd party stuff if possible. If you are interested in how I tested this (on Linux using the 'lsof' to list open files), my code is below:
object Test extends App {
import sys.process._
import scala.io.Source._
"echo hello world" #> new java.io.File("/tmp/testing") !
val src = fromFile("/tmp/testing")
val iter: Iterator[String] = src.getLines()
while (iter.hasNext) {
println("line=" + iter.next())
}
println("iterator exhausted.. sleeping while we check if file is still open using lsof")
Thread.sleep(200000)
}
After running the program and it is still sleeping, run this command:
lsof | grep /tmp/testing
and you will probably see output like this:
java 15813 ...253,0.... 12 .. lots-of-othernumbers..0462 /tmp/testing
Then when the program terminates, the grep will come up empty (as you would think).
Thanks in advance for any tips you can provide !
This is the pattern I tend to use:
def using[R <: Closeable, T](stream: R)(f: R => T): T =
try {
f(stream)
} finally {
stream.close()
}
Which you can use like so:
def readSomeLines(is: InputStream) = {
using(new BufferedReader(new InputStreamReader(is))) { stream =>
Iterator.continually(stream.readLine().takeWhile(_ != null)).foreach(println)
}
}
readSomeLines(new FileInputStream("/tmp/foo"))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With