加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – sys.process将进程包装为函数

发布时间:2020-12-16 08:53:02 所属栏目:安全 来源:网络整理
导读:我有一个外部过程,我想作为一个 函数来自String = String.给定一行输入,它将以单行输出响应.好像我应该用 scala.sys.process,这显然是一个优雅的库,可以创建很多 从scala中可以轻松访问shell操作.但是,我 无法弄清楚如何执行这个简单的用例. 如果我向进程’s
我有一个外部过程,我想作为一个
函数来自String => String.给定一行输入,它将以单行输出响应.好像我应该用
scala.sys.process,这显然是一个优雅的库,可以创建很多
从scala中可以轻松访问shell操作.但是,我
无法弄清楚如何执行这个简单的用例.

如果我向进程’stdin写一行,它会打印结果
在一条线上.我怎样才能使用sys.process来创建包装器
可以交互使用这个过程吗?例如,如果我有一个
ProcessWrapper的实现,这是一个程序,它的输出:

// abstract definition
class ProcessWrapper(executable: String) {
  def apply(line: String): String
}

// program using an implementation
val process = new ProcessWrapper("cat -b")
println(process("foo"))
println(process("bar"))
println(process("baz"))

输出:

1  foo
 2  bar
 3  baz

重要的是不要为每次调用进程重新加载进程,因为存在重要的初始化步骤.

解决方法

所以 – 在我的评论之后 – 这将是我的解决方案

import java.io.BufferedReader
import java.io.File
import java.io.InputStream
import java.io.InputStreamReader

import scala.annotation.tailrec

class ProcessWrapper(cmdLine: String,lineListenerOut: String => Unit,lineListenerErr: String => Unit,finishHandler: => Unit,lineMode: Boolean = true,envp: Array[String] = null,dir: File = null) {

  class StreamRunnable(val stream: InputStream,listener: String => Unit) extends Runnable {
    def run() {
      try {
        val in = new BufferedReader(new InputStreamReader(this.stream));
        @tailrec
        def readLines {
          val line = in.readLine
          if (line != null) {
            listener(line)
            readLines
          }
        }
        readLines
      }
      finally {
        this.stream.close
        finishHandler
      }
    }
  }
  val process = Runtime.getRuntime().exec(cmdLine,envp,dir);
  val outThread = new Thread(new StreamRunnable(process.getInputStream,lineListenerOut),"StreamHandlerOut")
  val errThread = new Thread(new StreamRunnable(process.getErrorStream,lineListenerErr),"StreamHandlerErr")
  val sendToProcess = process.getOutputStream
  outThread.start
  errThread.start

  def apply(txt: String) {
    sendToProcess.write(txt.getBytes)
    if (lineMode)
      sendToProcess.write('n')
    sendToProcess.flush
  }

}

object ProcessWrapper {
  def main(args: Array[String]) {
    val process = new ProcessWrapper("python -i",txt => println("py> " + txt),err => System.err.println("py err> " + err),System.exit(0))
    while (true) {
      process(readLine)
    }
  }
}

主要部分是StreamRunnable,其中进程在线程中读取,接收的行传递给“LineListener”(简单的String =>单元 – 函数).main只是一个示例实现 – 调用python;)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读