我想在scala中迭代一个文件并将其拆分为10 000行较小的文件。我怎么能这样做?
def splitFile(file: String, num: Int): Boolean = {
val buffer = "";
Source
.fromFile(file)
.getLines
.foreach((line: String, i: Int) => {
buffer = buffer + line;
if (i % num == 0) {
println(i);
}
});
};
现在我有类似的东西,但是 - foreach
循环没有迭代器。另外,我无法在scala中迭代变量 - cannot reassign variable
,not an Int type
等。我该怎么做?
答案 0 :(得分:2)
在具有split
二进制文件的* NIX系统上:
import sys.process._
s"split -l 10000 $filename" !
答案 1 :(得分:1)
如果你的文件很大(~500 MB)而且不是巨大的(~5 GB' s)。您可以使用以下功能。
import java.io.{BufferedWriter, File, FileWriter}
import scala.io.Source
def breakFileInPartsOfSizeN(filePath: String, n: Int): Unit = {
val fileSource = Source.fromFile(filePath)
val fileSourceLineIterator = fileSource.getLines()
def getNextBufferedFileWriter(i: Int) = {
val nextFilePath = filePath + ".part_" + i
val nextFile = new File(nextFilePath)
val bfw = new BufferedWriter(new FileWriter(nextFile))
bfw
}
def writeNextNLines(
i: Int,
n: Int,
remaining: Int,
lineIterator: Iterator[String],
bufferedFileWriterOption: Option[BufferedWriter] = None
): Unit = {
assert(n >= 0)
val bufferedFileWriter = (remaining, bufferedFileWriterOption) match {
case (0, None) => getNextBufferedFileWriter(i + 1)
case (0, Some(bfw)) =>
bfw.close()
getNextBufferedFileWriter(i + 1)
case (_, None) =>
getNextBufferedFileWriter(i)
case (_, Some(bfw)) => bfw
}
if (remaining == 0) {
writeNextNLines(i + 1, n, n, lineIterator, Some(bufferedFileWriter))
}
else if (lineIterator.hasNext) {
val line = lineIterator.next()
bufferedFileWriter.write(line + System.getProperty("line.separator"))
writeNextNLines(i, n, remaining - 1, lineIterator, Some(bufferedFileWriter))
}
else {
bufferedFileWriter.close()
// Well... we are done...
}
}
writeNextNLines(0, n, n, fileSourceLineIterator)
}
现在......你可以像这样使用它
breakFileInPartsOfSizeN("/your/file/absolute/path/filename.txt", 10000)
它将创建名为/your/file/absolute/path/filename.txt.part_n
答案 2 :(得分:0)
首先,如果要改变变量,请使用var
而不是val
。 var
是val
的可变选项
其次,你的foreach似乎错了。请检查以下代码:
Source
.fromFile(file)
.getLines
.foreach { line =>
buffer = buffer + line
}
我不太确定您想要的行号,但以下内容应该可以获得由num
定义的行数列表
val lines = Source.fromFile(file).getLines.toList
lines.grouped(num).toList
答案 3 :(得分:0)
val step = 10000
Source.fromFile(file).getLines
.sliding(step, step)
.zipWithIndex
.foreach { case (seq, i) =>
import java.io._
val pw = new PrintWriter(new File("filename" + i))
seq.foreach(pw.println)
pw.close
}