在Scala中,将整个文件读入内存的简单而规范的方法是什么?(理想情况下,可以控制字符编码。)

我能想到的最好的是:

scala.io.Source.fromPath("file.txt").getLines.reduceLeft(_+_)

或者我应该使用Java的一个可怕的习语,其中最好的(不使用外部库)似乎是:

import java.util.Scanner
import java.io.File
new Scanner(new File("file.txt")).useDelimiter("\\Z").next()

通过阅读邮件列表讨论,我甚至不清楚scala.io.Source是否应该是规范的I/O库。我不明白它的目的到底是什么。

... 我想要一些简单易记的东西。例如,在这些语言中,很难忘记成语……

Ruby    open("file.txt").read
Ruby    File.read("file.txt")
Python  open("file.txt").read()

当前回答

最明显的问题是“为什么要读取整个文件?”如果您的文件非常大,这显然不是一个可伸缩的解决方案。source从getLines方法返回一个Iterator[String],这非常有用和简洁。

使用底层java IO实用程序将File、Reader或InputStream转换为String并不是什么大工作。我认为缺乏可伸缩性意味着他们没有将其添加到标准API中是正确的。

其他回答

最明显的问题是“为什么要读取整个文件?”如果您的文件非常大,这显然不是一个可伸缩的解决方案。source从getLines方法返回一个Iterator[String],这非常有用和简洁。

使用底层java IO实用程序将File、Reader或InputStream转换为String并不是什么大工作。我认为缺乏可伸缩性意味着他们没有将其添加到标准API中是正确的。

你可以使用

Source.fromFile(fileName).getLines().mkString

但是应该注意的是,getLines()删除了所有新的行字符。 如果你想保存格式,你应该使用

Source.fromFile(fileName).iter.mkString

为了更快地读取/上传(大)文件,可以考虑增加bufferSize (Source. size)的大小。DefaultBufSize设置为2048),例如:

val file = new java.io.File("myFilename")
io.Source.fromFile(file, bufferSize = Source.DefaultBufSize * 2)

注意Source.scala。有关进一步讨论,请参阅Scala快速文本文件读取并上载到内存。

就像在Java中,使用CommonsIO库:

FileUtils.readFileToString(file, StandardCharsets.UTF_8)

此外,这里的许多答案忘记了Charset。最好总是显式地提供它,否则总有一天会出事。

有人告诉我Source.fromFile有问题。就我个人而言,我在使用Source.fromFile打开大文件时遇到过问题,不得不求助于Java InputStreams。

另一个有趣的解决方案是使用scalax。下面是一些注释良好的代码示例,它使用ManagedResource打开日志文件,使用scalax helper打开文件:http://pastie.org/pastes/420714