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

当前回答

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

其他回答

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

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

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

Java 8 +

import java.nio.charset.StandardCharsets
import java.nio.file.{Files, Paths}

val path = Paths.get("file.txt")
new String(Files.readAllBytes(path), StandardCharsets.UTF_8)

Java 11 +

import java.nio.charset.StandardCharsets
import java.nio.file.{Files, Path}

val path = Path.of("file.txt")
Files.readString(path, StandardCharsets.UTF_8)

它们提供了对字符编码的控制,并且不需要清理资源。由于更高效的分配模式,它也比其他模式(例如getLines(). mkstring ("\n"))更快。

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

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

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

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

相当于:

scala.io.Source.fromFile("test.txt" ).foreach( x => print(x))