Я запускаю и запускаю процесс Scala.Как написать строку Scala Process?
val dir = "/path/to/working/dir/"
val stockfish = Process(Seq("wine", dir + "stockfish_8_x32.exe"))
val logger = ProcessLogger(printf("Stdout: %s%n", _))
val stockfishProcess = stockfish.run(logger, connectInput = true)
Процесс считывает и записывает в стандартный IO (консоль). Как я могу отправить строковую команду процессу, если он уже запущен?
API-интерфейс Scala имеет ProcessBuilder, который имеет в свою очередь множество полезных методов. Но ProcessBuilder используется до, процесс начинает составлять сложные команды оболочки. Кроме того, Scala имеет ProcessIO для обработки ввода или вывода. Мне это тоже не нужно. Мне просто нужно отправить сообщение в мой процесс.
В Java я бы сделал что-то вроде этого.
String dir = "/path/to/working/dir/";
ProcessBuilder builder = new ProcessBuilder("wine", dir + "stockfish_8_x32.exe");
Process process = builder.start();
OutputStream stdin = process.getOutputStream();
InputStream stdout = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
new Thread(() -> {
try {
String line;
while ((line = reader.readLine()) != null) {
System.out.println("Stdout: " + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
Thread.sleep(5000); // it's just for example
writer.write("quit"); // send to the process command to stop working
writer.newLine();
writer.flush();
Это работает очень хорошо. Я запускаю свой процесс, получаю из него InputStream и OutputStream и использую потоки для взаимодействия с процессом.
Появилась черта Scala Process, которая не позволяет писать. ProcessBuilder бесполезен после запуска процесса. И ProcessIO предназначен только для ввода и обработки IO.
Есть ли способ написать процесс запуска Scala?
UPDATE:
Я не понимаю, как я могу использовать ProcessIO передать строку в процессе работы. Я сделал следующее.
import scala.io.Source
import scala.sys.process._
object Sample extends App {
def out = (output: java.io.OutputStream) => {
output.flush()
output.close()
}
def in = (input: java.io.InputStream) => {
println("Stdout: " + Source.fromInputStream(input).mkString)
input.close()
}
def go = {
val dir = "/path/to/working/dir/"
val stockfishSeq = Seq("wine", dir + "/stockfish_8_x32.exe")
val pio = new ProcessIO(out, in, err => {})
val stockfish = Process(stockfishSeq)
stockfish.run(pio)
Thread.sleep(5000)
System.out.write("quit\n".getBytes)
pio.writeInput(System.out) // "writeInput" is function "out" which I have passed to conforming ProcessIO instance. I can invoke it from here. It takes OutputStream but where can I obtain it? Here I just pass System.out for example.
}
go
}
Конечно, это не работает, и я не в состоянии понять, как реализовать функциональность, как и в моей Java сниппета выше. Было бы здорово иметь совет или фрагмент кода Scala, очищающего мою проблему.
Я думаю, что неправильно понял ваш вопрос, поэтому я удалил свой вопрос ответ. Вероятно, вам следует указать, какую версию Scala вы используете (я думаю, что API-интерфейсы, связанные с подпроцессом, недавно изменились). Я смущен, почему ProcessIO не работает для вас. Похоже, ваш код Java просто использует stdin/stdout, что также возможно с ProcessIO. Не могли бы вы уточнить? – DaoWen
@ DaoWen Да, на Java это довольно просто. Класс Java «Process» предоставляет методы, возвращающие потоки ввода-вывода, которые я могу использовать. Скала «Процесс» имеет только три метода: destroy, exitValue и isAlive. Класс ProcessIO имеет функциональный параметр «writeInput», который может быть передан и вызван впоследствии напрямую. Как я думаю, это просто слушатель для входных событий, но как создать это «событие» ?. Я использую последнюю версию Scala - 2.12.1. –