gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 07:55:52 25 4
gpt4 key购买 nike

我有一个外部流程,我想将其视为
函数来自 String=>String .给定一行输入,它将以一行输出作为响应。看来我应该用
scala.sys.process,这显然是一个优雅的库,它使许多
从 Scala 中轻松访问 shell 操作。但是,我
无法弄清楚如何执行这个简单的用例。

如果我向进程的标准输入写入一行,它会打印结果
在一行中。我如何使用 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

重要的是不要为每次调用 process 重新加载进程。因为有一个重要的初始化步骤。

最佳答案

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

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 => Unit - 函数)。
主要只是一个示例实现 - 调用 python ;)

关于scala - sys.process 将进程包装为函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14595349/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com