scala - 在 Scala 中与外部进程交互 (i/o)

标签 scala process io

我正在寻找一种简单的方法来启动外部进程,然后将字符串写入其输入并读取其输出。

在 Python 中,这是有效的:

mosesProcess = subprocess.Popen([mosesBinPath, '-f', mosesModelPath], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE);

# ...

mosesProcess.stdin.write(aRequest);
mosesAnswer = mosesProcess.stdout.readline().rstrip();

# ...

mosesProcess.stdin.write(anotherRequest);
mosesAnswer = mosesProcess.stdout.readline().rstrip();

# ...

mosesProcess.stdin.close();

我认为在 Scala 中这应该使用 scala.sys.process.ProcessBuilderscala.sys.process.ProcessIO 来完成,但我不明白它们是如何工作的(尤其是后者)。

编辑:

我尝试过以下方法:

val inputStream = new scala.concurrent.SyncVar[java.io.OutputStream];
val outputStream = new scala.concurrent.SyncVar[java.io.InputStream];
val errStream = new scala.concurrent.SyncVar[java.io.InputStream];

val cmd = "myProc";

val pb = process.Process(cmd);
val pio = new process.ProcessIO(stdin => inputStream.put(stdin),
  stdout => outputStream.put(stdout),
  stderr => errStream.put(stderr));

pb.run(pio);

inputStream.get.write(("request1" + "\n").getBytes);

println(outputStream.get.read); // It is blocked here

inputStream.get.write(("request2" + "\n").getBytes);

println(outputStream.get.read);

inputStream.get.close()

但是执行被卡住了。

最佳答案

当然,下面的 attrib 并不是写入方面的一个很好的例子。我有一个可以输入/输出的 EchoServer

    import scala.sys.process._
    import java.io._

    object EchoClient{
      def main(args: Array[String]) {
        var bContinue=true
        var cmd="C:\\\\windows\\system32\\attrib.exe"
        println(cmd)

        val process = Process (cmd)
        val io = new ProcessIO (
           writer,
           out => {scala.io.Source.fromInputStream(out).getLines.foreach(println)},
           err => {scala.io.Source.fromInputStream(err).getLines.foreach(println)})

        while (bContinue) {
          process run io
          var answer = readLine("Run again? (y/n)? ")
          if (answer=="n" || answer=="N")
            bContinue=false
        }
      }
      def reader(input: java.io.InputStream) = {
        // read here
      }

      def writer(output: java.io.OutputStream) = {
        // write here
        // 
      }

      // TODO: implement an error logger
    }

输出如下:

C:\\windows\system32\attrib.exe
A            C:\dev\EchoClient$$anonfun$1.class
A            C:\dev\EchoClient$$anonfun$2$$anonfun$apply$1.class
A            C:\dev\EchoClient$$anonfun$2.class
A            C:\dev\EchoClient$$anonfun$3$$anonfun$apply$2.class
A            C:\dev\EchoClient$$anonfun$3.class
A            C:\dev\EchoClient$.class
A            C:\dev\EchoClient.class
A            C:\dev\EchoClient.scala
A            C:\dev\echoServer.bat
A            C:\dev\EchoServerChg$$anonfun$main$1.class
A            C:\dev\EchoServerChg$.class
A            C:\dev\EchoServerChg.class
A            C:\dev\EchoServerChg.scala
A            C:\dev\ScannerTest$$anonfun$main$1.class
A            C:\dev\ScannerTest$.class
A            C:\dev\ScannerTest.class
A            C:\dev\ScannerTest.scala
Run again? (y/n)?

关于scala - 在 Scala 中与外部进程交互 (i/o),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30103040/

相关文章:

scala - 在 Scala 中是否有针对 Elasticsearch 的搜索词清理器的实现?

scala - 带有 RateLimiter 的 ExecutionContext

scala - 如何在 Scala 中定义自定义集合接口(interface)而不定义实现?

java - 用 Java 流畅地读取进程的输出

ruby - 在 ruby​​ 中使用其 PID 终止进程

c - POSIX 保证写入磁盘

java - 扫描仪在使用 next() 或 nextFoo() 后跳过 nextLine()?

scala - Play Framework for Scala - RESTful Web 服务

c - 进程同步

linux - 如何将 bash 输出写入任意程序标准输入