在Scala中将整个文件读入内存的简单和规范方法是什么?(理想情况下,控制字符编码.)
我能想到的最好的是:
scala.io.Source.fromPath("file.txt").getLines.reduceLeft(_+_)
Run Code Online (Sandbox Code Playgroud)
或者我应该使用Java的一个令人难以置信的习语,其中最好的(不使用外部库)似乎是:
import java.util.Scanner
import java.io.File
new Scanner(new File("file.txt")).useDelimiter("\\Z").next()
Run Code Online (Sandbox Code Playgroud)
从阅读邮件列表讨论来看,我不清楚scala.io.Source甚至应该是规范的I/O库.我完全不明白它的目的是什么.
...我想要一些简单易记的东西.例如,在这些语言中,很难忘记这些成语......
Ruby open("file.txt").read
Ruby File.read("file.txt")
Python open("file.txt").read()
Run Code Online (Sandbox Code Playgroud)
Dan*_*ral 420
val lines = scala.io.Source.fromFile("file.txt").mkString
Run Code Online (Sandbox Code Playgroud)
顺便说一句," scala."并不是必需的,因为它总是在范围内,当然,您可以完全或部分地导入io的内容,并且避免必须添加"io".太.
但是,上面的文件保持打开状态.为避免出现问题,您应该像这样关闭它:
val source = scala.io.Source.fromFile("file.txt")
val lines = try source.mkString finally source.close()
Run Code Online (Sandbox Code Playgroud)
上面代码的另一个问题是,由于它的实现性质,它很慢.对于较大的文件,应使用:
source.getLines mkString "\n"
Run Code Online (Sandbox Code Playgroud)
Dan*_*wak 56
只是为了扩展Daniel的解决方案,您可以通过将以下导入插入到需要文件操作的任何文件中来极大地缩短范围:
import scala.io.Source._
Run Code Online (Sandbox Code Playgroud)
有了这个,你现在可以做到:
val lines = fromFile("file.txt").getLines
Run Code Online (Sandbox Code Playgroud)
我会警惕将整个文件读成单个文件String.这是一个非常糟糕的习惯,会比你想象的更快,更难咬你.该getLines方法返回type的值Iterator[String].它实际上是一个放入文件的懒惰光标,允许您只检查所需的数据而不会有内存过剩的风险.
哦,并回答你的隐含问题Source:是的,它是规范的I/O库.大多数代码java.io由于其较低级别的接口和与现有框架的更好兼容性而最终使用,但是任何有选择的代码都应该使用Source,特别是对于简单的文件操作.
Wal*_*ang 36
// for file with utf-8 encoding
val lines = scala.io.Source.fromFile("file.txt", "utf-8").getLines.mkString
Run Code Online (Sandbox Code Playgroud)
psp*_*psp 26
(编辑:这在scala 2.9中不起作用,也许不是2.8)
使用trunk:
scala> io.File("/etc/passwd").slurp
res0: String =
##
# User Database
#
... etc
Run Code Online (Sandbox Code Playgroud)
Pau*_*per 18
import java.nio.charset.StandardCharsets._
import java.nio.file.{Files, Paths}
new String(Files.readAllBytes(Paths.get("file.txt")), UTF_8)
Run Code Online (Sandbox Code Playgroud)
控制字符编码,无需清理资源.此外,可能已经优化(例如,Files.readAllBytes分配适合于文件大小的字节数组).
小智 6
在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)
}
Run Code Online (Sandbox Code Playgroud)
就像在Java中一样,使用CommonsIO库:
FileUtils.readFileToString(file, StandardCharsets.UTF_8)
Run Code Online (Sandbox Code Playgroud)
此外,许多答案在这里忘记了Charset.最好总是明确地提供它,否则它会在一天内发布.
还有一个: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
Run Code Online (Sandbox Code Playgroud)
您也可以为进行读/写的任何操作提供自己的编解码器(如果不提供,则假定为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")
Run Code Online (Sandbox Code Playgroud)
如果你不介意第三方依赖,你应该考虑使用我的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")
Run Code Online (Sandbox Code Playgroud)
具有用于读取字节、读取块、读取行和许多其他有用/常见操作的单行助手
| 归档时间: |
|
| 查看次数: |
210588 次 |
| 最近记录: |