我正在用scala替換很多我的perl。我傾向於做的很多事情之一是由我公司的其他團隊提供給我的調用二進制文件(通常編譯爲C++,但可能是java,其他perl腳本,q腳本等)。例如,爲了做一些複雜的數學運算,我會啓動一個外部二進制文件,然後將輸入傳送給它。然後,我會傾聽其stdout
流的結果,以及stderr
流的診斷消息。在perl中,我會使用POE::Wheel::Run
小部件來完成此操作。我在scala中提出了一些類似的(並且更好的),但是我想讓它更加強大。這是一個圍繞ProcessIO
對象的小包裝。它看起來像這樣:斯卡拉 - 當外部進程退出時得到回調
class Exe(command: String, out: String => Unit, err: String => Unit) {
import scala.sys.process._
import scala.io._
import java.io._
import scala.concurrent._
val inputStream = new SyncVar[OutputStream];
val process = Process(command).run(
new ProcessIO(
stdin => inputStream.put(stdin),
stdout => Source.fromInputStream(stdout).getLines.foreach(out),
stderr => Source.fromInputStream(stderr).getLines.foreach(err)));
def write(s: String): Unit = synchronized {
inputStream.get.write((s + "\n").getBytes)
}
def close(): Unit = {
inputStream.get.close
}
}
我會再使用這樣的:
val exe = new Exe("tr [a-z] [A-Z]",
out => println("o: " + out),
err => println("e: " + err))
exe.write("lower")
exe.close()
打印出:
o: LOWER
這讓我90%有,但會是什麼當進程退出時,好的方法是獲得回調。它可能會因爲我關閉了輸入流並且其內部循環停止而退出,它可能會自行退出,或者它可能會因爲我殺死它而退出。在回調中,最好知道它爲什麼停止,並退出代碼。
我對如何去做這件事感到有點不知所措,任何幫助將不勝感激(並且對上述代碼的任何編輯當然都是受歡迎的 - 我有點小菜鳥) 。
我使用2.9.0.1
就我個人而言,我認爲糟糕的是'Process'沒有某種'isFinished'輪詢方法。這是我會改變的一件事,儘管didierd提供的解決方案看起來更像你想要的。 –