我有一个大的日志文件,其客户端ID是每个日志行中的一个字段。我想将这个大型日志文件拆分为多个按客户端ID分组的文件。因此,如果原始文件有10行,其中包含10个唯一的client-id,那么最后将有10个文件,每个文件包含1行。
我试图在Scala中执行此操作,并且不希望将整个文件加载到内存中,使用scala.io.Source.getLines()一次加载一行。这很好用。但是,我没有一个好的方法可以将它写入一次分隔一行文件。我可以想到两个选择:
为每一行创建一个由BufferedWriter(Files.newBufferedWriter)支持的新PrintWriter。这似乎效率低下。
为每个输出文件创建一个由BufferedWriter支持的新PrintWriter,保留这些PrintWriters并继续写入它们,直到我们读取原始日志文件中的所有行并关闭它们。在Scala中,这似乎不是一种非常实用的方法。
作为Scala的新手,我不确定还有其他更好的方法来完成这样的事情。任何想法或想法都非常感激。
答案 0 :(得分:0)
你可以在非常实用的惯用Scala中做第二个选项。您可以跟踪文件行中的所有PrintWriters
和fold
:
import java.io._
import scala.io._
Source.fromFile(new File("/tmp/log")).getLines.foldLeft(Map.empty[String, PrintWriter]) {
case (printers, line) =>
val id = line.split(" ").head
val printer = printers.get(id).getOrElse(new PrintWriter(new File(s"/tmp/log_$id")))
printer.println(line)
printers.updated(id, printer)
}.values.foreach(_.close)
也许在生产级版本中,您希望将I / O操作包装在try
(或Try
)中,并以这种方式跟踪失败,同时仍然{{1最后的所有closing
。