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

时间:2009-11-19 12:06:28

标签: scala file-io

我正在使用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")

  }

Source有一个名为reset的方法,但是所有这一切都是从文件中重新创建源。

内部Source创建一个具有BufferedSource方法的基础close。然而,这并未从Source公开。

我希望Source在读取文件内容后释放文件句柄,但似乎不会这样做。

到目前为止,我看到的最佳解决方法是将Source基本上转换为BufferedSource并致电close

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

或者,我可以从Source创建InputStream并自行管理结算。

然而,这似乎有些。使用Source时,您应该如何释放文件句柄?

3 个答案:

答案 0 :(得分:16)

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

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

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

答案 1 :(得分:6)

在Scala 2.8.x中进行一些修改。 “getLines” - > “getLines()”

...
src.getLines().foreach(l => print(l))
...

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

答案 2 :(得分:4)

据我所知,io.Source仍然在2.8中被破坏(连接被泄露等),所以应该阻止人们使用它。

正如David上面提到的那样,直到替换lib http://github.com/scala-incubator/scala-io被合并(可能在2.8之后),最好的选择是继续使用纯Java库,如apache commons-io等。