是的,虽然它不是那么简洁:
import java.io.File
import scala.io.Source
for {
file <- new File(dir).listFiles.toIterator if file.isFile
line <- Source fromFile file getLines
} { doSomething line }
诀窍是flatMap
和它的for
理解语法糖。例如,上述内容或多或少等同于以下内容:
new File(dir)
.listFiles.toIterator
.filter(_.isFile)
.flatMap(Source fromFile _ getLines)
.map(doSomething)
正如 Daniel Sobral 在下面的评论中指出的那样,这种方法(以及您问题中的代码)将使文件保持打开状态。如果这是一次性脚本,或者您只是在 REPL 中工作,这可能没什么大不了的。如果确实遇到问题,可以使用pimp-my-library 模式来实现一些基本的资源管理:
implicit def toClosingSource(source: Source) = new {
val lines = source.getLines
var stillOpen = true
def getLinesAndClose = new Iterator[String] {
def hasNext = stillOpen && lines.hasNext
def next = {
val line = lines.next
if (!lines.hasNext) { source.close() ; stillOpen = false }
line
}
}
}
现在只需使用Source fromFile file getLinesAndClose
,您就不必担心文件处于打开状态。