如何在Scala中流式输出stdout?

pyt*_*nic 2 java scala apache-spark

基本上,我有一个程序,其输出将输出到stdout。我正在我的Scala代码中运行该程序。我现在要做的是将输出重定向到文件。这样的事情。

val cmd = progName + " " + arguments 
cmd #> new java.io.File(outputFilePath) !
Run Code Online (Sandbox Code Playgroud)

我还必须稍后处理该输出文件。这就是为什么这种方法很慢的原因,因为我必须首先等待程序完成并将所有内容写入输出文件。我更希望的是流式输出stdout的内容,以便在流式传输时可以从另一个线程读取内容。这样,我可以在从Scala运行的程序运行时处理数据。

此外,输出文件中的数据由换行符分隔。有没有办法,我可以在程序运行时逐行获取数据。

最后,在Java中有什么可以做的,然后我也可以在Scala中使用?

Dao*_*Wen 5

ProcessBuilder有一个lineStream方法,我认为它确实可以满足您的需求。它返回一个Stream[String],使您可以在输出可用时对其进行处理。

这是一个简单的程序,输出测试缓慢,我将其保存为slow-printer.scala

// slow-printer.scala
for (i <- 1 to 10) {
  println(i)
  Thread.sleep(1000)
}
Run Code Online (Sandbox Code Playgroud)

您可以像这样通过流传输程序的输出(每秒1行):

import scala.sys.process._

val lines = "scala slow-printer.scala".lineStream

lines foreach println
Run Code Online (Sandbox Code Playgroud)

如果您坚持使用2.10,或者您的输出不是用换行符分隔的,则可以使用ProcessIO来处理输出:

import scala.sys.process._

Seq("scala", "slow-printer.scala").run(new ProcessIO(
  _.close(), // stdin
  out => { // stdout
    val src = scala.io.Source.fromInputStream(out)
    for (line <- src.getLines()) {
      println(line)
    }
  },
  _.close() // stderr
))
Run Code Online (Sandbox Code Playgroud)