[英]How to stream stdout in Scala?
Basically, I have a program whose output goes to stdout. 基本上,我有一个程序,其输出将输出到stdout。 I am running that program from within my Scala code. 我正在我的Scala代码中运行该程序。 What I do right now is to redirect the output to a file. 我现在要做的是将输出重定向到文件。 Something like this. 这样的事情。
val cmd = progName + " " + arguments
cmd #> new java.io.File(outputFilePath) !
I also have to later process that output file. 我还必须稍后处理该输出文件。 That is why this approach is slow, as I have to first wait for the program to have finished and everything written to the output file. 这就是为什么这种方法很慢的原因,因为我必须首先等待程序完成并将所有内容写入输出文件。 What I would prefer is to have content of the stdout being streamed so that from another thread I could read the contents as they are being streamed. 我更希望的是流式输出stdout的内容,以便在流式传输时可以从另一个线程读取内容。 In this way, I can process the data while the program I am running from Scala is running. 这样,我可以在从Scala运行的程序运行时处理数据。
Moreover, the data in the output file is delimited by newlines. 此外,输出文件中的数据由换行符分隔。 Is there a way, I could get the data line by line as the program is running. 有没有办法,我可以在程序运行时逐行获取数据。
Lastly, is there something in Java to do that, which I can also then use in Scala? 最后,在Java中有什么可以做的,然后我也可以在Scala中使用?
The ProcessBuilder has a lineStream
method, which I think does exactly what you want. ProcessBuilder有一个lineStream
方法,我认为它确实可以实现您想要的功能。 It returns a Stream[String]
that lets you process the output as it becomes available. 它返回一个Stream[String]
,让您在输出可用时对其进行处理。
Here's a simple program with slow output for testing, which I saved as slow-printer.scala
: 这是一个简单的程序,用于测试输出缓慢,我将其保存为slow-printer.scala
:
// slow-printer.scala
for (i <- 1 to 10) {
println(i)
Thread.sleep(1000)
}
You can stream the output (1 line per second) from the program like this: 您可以像这样通过流传输程序的输出(每秒1行):
import scala.sys.process._
val lines = "scala slow-printer.scala".lineStream
lines foreach println
If you're stuck with 2.10, or maybe if your output isn't newline-delimited, then you can use ProcessIO
to handle the output instead: 如果您坚持使用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
))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.