Java 在Scala中将大型日志文件拆分为多个文件
我有一个很大的日志文件,每个日志行中的一个字段是客户机id。我想将这个大日志文件拆分为几个按客户机id分组的文件。因此,如果原始文件有10行10个唯一的客户机id,那么最后将有10个文件,每个文件中有1行 我尝试在Scala中执行此操作,但不想将整个文件加载到内存中,请使用Scala.io.Source.getLines()一次加载一行。这很有效。但是,我没有一个很好的方法把它一行一行地写在单独的文件中。我可以想出两个选择:Java 在Scala中将大型日志文件拆分为多个文件,java,scala,functional-programming,nio,Java,Scala,Functional Programming,Nio,我有一个很大的日志文件,每个日志行中的一个字段是客户机id。我想将这个大日志文件拆分为几个按客户机id分组的文件。因此,如果原始文件有10行10个唯一的客户机id,那么最后将有10个文件,每个文件中有1行 我尝试在Scala中执行此操作,但不想将整个文件加载到内存中,请使用Scala.io.Source.getLines()一次加载一行。这很有效。但是,我没有一个很好的方法把它一行一行地写在单独的文件中。我可以想出两个选择: 为每一行创建一个由缓冲写入程序(Files.newBufferedWr
作为Scala的新手,我不确定是否还有其他更好的方法来完成类似的任务。非常感谢您的任何想法或想法。您可以使用功能强大、惯用的Scala完成第二个选项。您可以跟踪所有的
打印作者
,并在文件行上折叠:
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
)中,并以这种方式跟踪故障,同时仍然closing
所有PrintWriters
。为什么这是标记Java?我认为(与语言无关),您必须咬紧牙关。或者每行创建一个新的编写器;或者“每个”输出文件创建一个writer——但这意味着所有这些writer都应该保持活动状态(我认为这没有什么大问题;除非我们讨论的是太多的输出writer……以至于应用程序的OS文件句柄都用光了)。我同意@Jägermeister的观点。要添加更多现成的想法,您可以:1.-首先按客户机id对文件进行排序(可能直接使用linux排序),然后每次只需读取1个文件并写入1个文件。2.-使用某种map reduce平台,如Spark,在3行代码中完成这项工作,忘记细节。当然,这完全取决于你的最终目标是什么。这个解决方案对我有效。foldLeft中是否需要“case”关键字,似乎没有它也可以工作?是的--您可以在这里省略case
!