在Scala中读取文件:Stream已关闭

时间:2016-11-07 07:59:00

标签: scala

我尝试在scala中读取这样的文件:

from collections import Counter
c=dict(Counter('abbccdeefght'))# get counts as dictionary
last_duplicate = list(filter(lambda k: c[k] == 2, c.keys()))[-1]#get only duplicates and take the last one

当我稍后访问结果时,我得到了一个

def parseFile(filename: String) = {
  val source = scala.io.Source.fromFile(filename)
  try {
    val lines = source.getLines().map(line => line.trim.toDouble)
    return lines
  } catch {
    // re-throw exception, but make source source is closed
    case
      t: Throwable => {
      println("error during parsing of file")
      throw t
    }
  } finally {
    source.close()
  }
}

我理解这是因为java.io.IOException: Stream Closed 只返回(懒惰)source.getLines(),我已经关闭了Iterator[String]子句中的BufferedSource

如何避免此错误,即"如何评估"关闭源之前的流?

编辑:我试图拨打finally但没有帮助。

2 个答案:

答案 0 :(得分:0)

也许,您可以尝试以下解决方案,这使代码更具功能性并利用延迟评估。

首先,定义一个辅助函数using,它负责打开/关闭文件。

def using[A <: {def close() : Unit}, B](param: A)(f: A => B): B =
    try f(param) finally param.close()

然后,您可以在函数式编程风格中重构代码:

using(Source.fromFile(filename)) {
  source =>
    val lines = Try(source.getLines().map(line => line.trim.toDouble))
    val result = lines.flatMap(l => Try(processOrDoWhatYouWantForLines(l)))
    result.get
}

实际上,using函数可用于处理在操作结束时需要关闭的所有资源。

答案 1 :(得分:0)

列表不是很懒,所以请更改:

val lines = source.getLines().map(line => line.trim.toDouble)

val lines = source.getLines().toList.map(line => line.trim.toDouble)

为了强制计算。