为什么Scala Source不关闭底层的InputStream?

pjp*_*pjp 16 file-io scala

我正在使用Scala,Source.fromFile但是一旦读取了文件,我似乎无法找到一种很好的方法将它close传入底层InputStream.

这是我的代码,AssertionError因为无法删除文件而失败.

  def main(args : Array[String]) : Unit = {

    val myFile = new File("c:/tmp/doodah.txt")
    var src = Source.fromFile(myFile)
    src.getLines.foreach(l => print(l))

    val deleted: Boolean = myFile.delete

    assert (deleted , "File was not deleted - maybe the stream hasn't been closed in Source")

  }
Run Code Online (Sandbox Code Playgroud)

Source有一个被调用的方法,reset但是这样做会重新创建文件中的源.

内部Source创建一个BufferedSource具有close方法的底层.但是,这不是从Source公开的.

我希望Source在读取文件内容后释放文件句柄,但似乎没有这样做.

到目前为止,我看到的最佳解决方法是基本上将其转换Source为a BufferedSource和call close.

try {
  src.getLines.foreach(l => print(l))
}
finally src match { case b: scala.io.BufferedSource => b.close }
Run Code Online (Sandbox Code Playgroud)

或者,我可以创建一个Source来自InputStream管理结束我自己.

然而,这似乎有点.使用时你应该如何释放文件句柄Source

Dan*_*ral 16

Scala.io._是为了支持XML库和编译器而创建的准系统hack.它的设计很糟糕,并且遇到很多问题.Scala 2.8将声称它的改进版本,虽然几乎没有什么可写回家的.

有兴趣的各方正在进行第三方努力,以开发一个健全的Scala I/O库.它旨在将JDK7 I/O重新设计的经验教训带回家,同时提供Scala-ish API.

同时......只要您的应用程序偶然发现当前库的设计问题,就使用Java库.


Wal*_*ang 6

适用于Scala 2.8.x并稍加修改."getLines" - >"getLines()"

...
src.getLines().foreach(l => print(l))
...
Run Code Online (Sandbox Code Playgroud)

2.8.x中的scala.io.Source比2.7.x中的对应物更好,并且正确关闭了InputStream.

  • 您为什么认为Source会关闭其输入流?AFAIK,不是。我只是看了看源代码,找不到能做到这一点的任何东西,REPL的一个小测试显示,即使迭代器为空,文件描述符仍保持打开状态。 (2认同)