Zamierzam zastąpić wiele moich perl scala. Jedną z rzeczy, które często robię, to binarne wywołania (zwykle kompilowane w C++, ale może to być Java, inne skrypty perla, q skrypty itp.) Dostarczone mi przez inne zespoły w mojej firmie.Scala - uzyskiwanie wywołania zwrotnego, gdy zewnętrzny proces kończy się.
Na przykład, aby wykonać skomplikowaną matematykę, zacznę od jednego z zagranicznych plików binarnych, a następnie dodam do niego dane wejściowe. Następnie wysłucham jego strumienia stdout
dla wyników i strumienia stderr
dla komunikatów diagnostycznych. W perlu zrobiłbym to za pomocą widgetu POE::Wheel::Run
. Wymyśliłem coś podobnego (i dużo ładniejszego) w scala, ale chciałbym, aby było bardziej solidne. Jest to małe opakowanie wokół obiektu ProcessIO
. Wygląda to tak:
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
}
}
bym następnie używać go tak:
val exe = new Exe("tr [a-z] [A-Z]",
out => println("o: " + out),
err => println("e: " + err))
exe.write("lower")
exe.close()
Który wypisuje:
o: LOWER
To dostaje mi 90% tam, ale co byłoby miło byłoby uzyskać wywołanie zwrotne po zakończeniu procesu. Może wyjść, ponieważ zamknąłem strumień wejściowy i jego wewnętrzna pętla zatrzymuje się, może wyjść samodzielnie lub może wyjść, ponieważ ją zabiłem. W wywołaniu zwrotnym dobrze byłoby wiedzieć, dlaczego się zatrzymał, i kod wyjścia.
Jestem trochę zagubiony, jak to zrobić, każda pomoc byłaby doceniona (i wszelkie zmiany powyższego kodu są oczywiście mile widziane - jestem trochę noob) .
Używam 2.9.0.1
Osobiście uważam, że to jest do bani, że 'Proces' nie ma jakiejś metody odpytywania' isFinished'. To jedna rzecz, którą chciałbym zmienić, chociaż rozwiązanie dostarczone przez didierd wydaje się bardziej podobne do tego, co chcesz. –