【问题标题】:Why doesn't Scala Source close the underlying InputStream?为什么 Scala Source 不关闭底层 InputStream?
【发布时间】:2010-12-18 06:48:27
【问题描述】:

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

或者,我可以从InputStream 创建一个Source 并自己管理关闭。

不过这似乎有点。使用Source时应该如何释放文件句柄?

【问题讨论】:

    标签: scala file-io


    【解决方案1】:

    Scala.io._ 是一个准系统黑客,其唯一目的是支持 XML 库和编译器。它的设计很糟糕,并且存在许多问题。 Scala 2.8 将声称是它的改进版本,但几乎没有什么可写的。

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

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

    【讨论】:

    • @DCS “正在进行的第三方工作”的链接或名称?
    • @C.W.HolemanII Scala I/O,遗憾的是,在两年半之后,它仍然不是标准库的一部分。
    【解决方案2】:

    稍加修改即可在 Scala 2.8.x 中使用。 “getLines”->“getLines()”

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

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

    【讨论】:

    • 为什么需要在 2.8 中使用空括号?
    • 因为getLines 方法在 2.8 中有一个参数,默认为平台的 EOL 字符。请注意,默认参数已在 2.8 中添加
    • 请注意,目前在 Scala 2.9.0.1 中 Source.getLines 已损坏:issues.scala-lang.org/browse/SI-4662
    • 你认为Source为什么会关闭它的输入流? AFAIK,它没有。我只是查看了源代码,找不到任何可以做到这一点的东西,来自 REPL 的一个简单测试表明,即使迭代器为空,文件描述符仍然保持打开状态。
    【解决方案3】:

    据我所知 io.Source 在 2.8 中仍然存在问题(连接泄露等),因此不鼓励人们使用它。

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

    【讨论】:

    • UPD:链接的问题已在将近一年前修复
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-12
    • 1970-01-01
    相关资源
    最近更新 更多