将大型日志文件拆分为Scala中的多个文件

时间:2015-04-08 14:24:51

标签: java scala functional-programming nio

我有一个大的日志文件,其客户端ID是每个日志行中的一个字段。我想将这个大型日志文件拆分为多个按客户端ID分组的文件。因此,如果原始文件有10行,其中包含10个唯一的client-id,那么最后将有10个文件,每个文件包含1行。

我试图在Scala中执行此操作,并且不希望将整个文件加载到内存中,使用scala.io.Source.getLines()一次加载一行。这很好用。但是,我没有一个好的方法可以将它写入一次分隔一行文件。我可以想到两个选择:

  1. 为每一行创建一个由BufferedWriter(Files.newBufferedWriter)支持的新PrintWriter。这似乎效率低下。

  2. 为每个输出文件创建一个由BufferedWriter支持的新PrintWriter,保留这些PrintWriters并继续写入它们,直到我们读取原始日志文件中的所有行并关闭它们。在Scala中,这似乎不是一种非常实用的方法。

  3. 作为Scala的新手,我不确定还有其他更好的方法来完成这样的事情。任何想法或想法都非常感激。

1 个答案:

答案 0 :(得分:0)

你可以在非常实用的惯用Scala中做第二个选项。您可以跟踪文件行中的所有PrintWritersfold

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