0

我需要从 128M 的文件中读取一些数据,然后对于每一行,我都会做一些处理,天真的方法是使用 split 将字符串转换为行集合,然后处理每一行,但也许那无效,因为它会创建一个简单地存储临时结果的集合,这可能是昂贵的。有没有性能更好的方法?

文件很大,所以我启动了几个线程,每个线程会拾取128个chuck,在下面的脚本中rawString是一个128M的chuck。

randomAccessFile.seek(start)
randomAccessFile.read(byteBuffer)
val rawString = new String(byteBuffer)
val lines=rawString.split("\n")
for(line <- lines){
    ...
}
4

2 回答 2

2

最好逐行阅读文本:

import scala.io.Source
for(line <- Source.fromFile("file.txt").getLines()) {
  ...
}
于 2013-05-16T06:09:28.183 回答
1

我不确定你将如何处理块开头和结尾的行尾。我将把它留给你来解决——这个解决方案捕获了两边由\n.

无论如何,假设它byteBuffer实际上是一个字节数组而不是 a java.nio.ByteBuffer,并且你可以处理 Unix 行编码,你会想要

def lines(bs: Array[Byte]): Array[String] = {
  val xs = Array.newBuilder[Int]
  var i = 0
  while (i<bs.length) {
    if (bs(i)=='\n') xs += i
    i += 1
  }
  val ix = xs.result
  val ss = new Array[String](0 max (ix.length-1))
  i = 1
  while (i < ix.length) {
    ss(i-1) = new String(bs, ix(i-1)+1, ix(i)-ix(i-1)-1)
    i += 1
  }
  ss
}

当然,这是相当长且混乱的代码,但是如果您真的担心性能,那么这种事情(大量使用对原语的低级操作)是可行的方法。(这也只需要大约 3 倍的磁盘块内存,而不是大约 5 倍(对于大部分/完全 ASCII 数据),因为您不需要完整的字符串表示。)

于 2013-05-16T06:48:13.620 回答