在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()

当前回答

正如一些人提到的,scala.io.Source最好避免使用,因为它会导致连接泄漏。

也许scalax和像commons-io这样的纯java库是最好的选择,直到新的孵化器项目(即scala-io)被合并。

其他回答

在scala.io.Source上使用getLines()会丢弃用于行结束符的字符(\n, \r, \r\n等)。

下面应该保持字符对字符,并且不会进行过多的字符串连接(性能问题):

def fileToString(file: File, encoding: String) = {
  val inStream = new FileInputStream(file)
  val outStream = new ByteArrayOutputStream
  try {
    var reading = true
    while ( reading ) {
      inStream.read() match {
        case -1 => reading = false
        case c => outStream.write(c)
      }
    }
    outStream.flush()
  }
  finally {
    inStream.close()
  }
  new String(outStream.toByteArray(), encoding)
}

你可以使用

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

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

Source.fromFile(fileName).iter.mkString

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

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

你也可以使用scala io中的Path来读取和处理文件。

import scalax.file.Path

现在你可以得到文件路径使用这个:-

val filePath = Path("path_of_file_to_b_read", '/')
val lines = file.lines(includeTerminator = true)

您也可以包含终止符,但默认设置为false..

还有一个:https://github.com/pathikrit/better-files#streams-and-codecs

有多种方法可以在不将内容加载到内存的情况下获取文件:

val bytes  : Iterator[Byte]            = file.bytes
val chars  : Iterator[Char]            = file.chars
val lines  : Iterator[String]          = file.lines
val source : scala.io.BufferedSource   = file.content 

你也可以为任何执行读/写操作的东西提供你自己的编解码器(如果你没有提供,它会假设scala.io.Codec.default):

val content: String = file.contentAsString  // default codec
// custom codec:
import scala.io.Codec
file.contentAsString(Codec.ISO8859)
//or
import scala.io.Codec.string2codec
file.write("hello world")(codec = "US-ASCII")