在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()
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"))更快。
在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)
}