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

当前回答

为了模拟打开和读取文件的Ruby语法(以及传递语义),可以考虑以下隐式类(Scala 2.10及更高版本),

import java.io.File

def open(filename: String) = new File(filename)

implicit class RichFile(val file: File) extends AnyVal {
  def read = io.Source.fromFile(file).getLines.mkString("\n")
}

这样,

open("file.txt").read

其他回答

val lines = scala.io.Source.fromFile("file.txt").mkString

顺便说一下,“scala.”并不是真正必要的,因为它总是在作用域中,当然,您可以完全或部分地导入io的内容,而不必在前面加上“io.”。

但是,上面的操作使文件保持打开状态。为了避免问题,你应该像这样关闭它:

val source = scala.io.Source.fromFile("file.txt")
val lines = try source.mkString finally source.close()

上面代码的另一个问题是,由于它的实现,它非常慢。对于较大的文件,应该使用:

source.getLines mkString "\n"
// for file with utf-8 encoding
val lines = scala.io.Source.fromFile("file.txt", "utf-8").getLines.mkString

打印每一行,就像使用Java BufferedReader读取每一行,然后打印它:

scala.io.Source.fromFile("test.txt" ).foreach{  print  }

相当于:

scala.io.Source.fromFile("test.txt" ).foreach( x => print(x))
import scala.io.source
object ReadLine{
def main(args:Array[String]){
if (args.length>0){
for (line <- Source.fromLine(args(0)).getLine())
println(line)
}
}

在参数中,你可以给出文件路径,它会返回所有行

如果您不介意第三方依赖,您应该考虑使用我的OS-Lib库。这使得读取/写入文件和使用文件系统非常方便:

// Make sure working directory exists and is empty
val wd = os.pwd/"out"/"splash"
os.remove.all(wd)
os.makeDir.all(wd)

// Read/write files
os.write(wd/"file.txt", "hello")
os.read(wd/"file.txt") ==> "hello"

// Perform filesystem operations
os.copy(wd/"file.txt", wd/"copied.txt")
os.list(wd) ==> Seq(wd/"copied.txt", wd/"file.txt")

使用单行帮助程序,用于读取字节、读取块、读取行和许多其他有用/常见操作