java 中的 Runtime.exec() 挂起,因为它正在等待来自 System.in 的输入
Runtime.exec() in java hangs because it is waiting for input from System.in
我有以下简短的 python 程序 "test.py"
n = int(raw_input())
print n
我正在从以下 java 程序 "ProcessRunner.java"
中执行上述程序
import java.util.*;
import java.io.*;
public class ProcessRunner {
public static void main(String[] args) {
try {
Scanner s = new Scanner(Runtime.getRuntime().exec("python test.py").getInputStream()).useDelimiter("\A");
System.out.println(s.next());
}
catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
根据运行命令,
java ProcessRunner
我无法将正确格式的值 'n' 传递给 Python 程序,而且 java 运行 挂起。处理这种情况并从 java 程序内部将值动态传递给 'n' 到 python 程序的正确方法是什么?
raw_input()
, or input()
in Python 3,将阻塞等待标准输入上的新行终止输入,但是,Java 程序不会发送任何内容。
尝试使用 getOutputStream()
返回的流写入 Python 子进程。这是一个例子:
import java.util.*;
import java.io.*;
public class ProcessRunner {
public static void main(String[] args) {
try {
Process p = Runtime.getRuntime().exec("python test.py");
Scanner s = new Scanner(p.getInputStream());
PrintWriter toChild = new PrintWriter(p.getOutputStream());
toChild.println("1234"); // write to child's stdin
toChild.close(); // or you can use toChild.flush()
System.out.println(s.next());
}
catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
另一种方法是将 n
作为命令行参数传递。这需要修改 Python 脚本以预期和处理命令行参数,并修改 Java 代码以发送参数:
import java.util.*;
import java.io.*;
public class ProcessRunner {
public static void main(String[] args) {
try {
int n = 1234;
Process p = Runtime.getRuntime().exec("python test.py " + n);
Scanner s = new Scanner(p.getInputStream());
System.out.println(s.next());
}
catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
和 Python 脚本,test.py
:
import sys
if len(sys.argv) > 1:
print int(sys.argv[1])
如果我理解正确的话,你希望你的 java 程序将你的 python 脚本的任何输出传递给 System.out,并将你的 java 程序的任何输入传递给你的python 脚本,对吗?
查看以下程序以了解如何执行此操作。
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class ProcessRunner {
public static void main(String[] args) {
try {
final Process process = Runtime.getRuntime().exec("/bin/sh");
try (
final InputStream inputStream = process.getInputStream();
final InputStream errorStream = process.getErrorStream();
final OutputStream outputStream = process.getOutputStream()
) {
while (process.isAlive()) {
forwardOneByte(inputStream, System.out);
forwardOneByte(errorStream, System.err);
forwardOneByte(System.in, outputStream);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static void forwardOneByte(final InputStream inputStream,
final OutputStream outputStream)
throws IOException {
if(inputStream.available() <= 0) {
return;
}
final int b = inputStream.read();
if(b != -1) {
outputStream.write(b);
outputStream.flush();
}
}
}
注意这段代码只是一个概念演示。它会耗尽您的 cpu 并且无法处理更大的吞吐量。
我有以下简短的 python 程序 "test.py"
n = int(raw_input())
print n
我正在从以下 java 程序 "ProcessRunner.java"
中执行上述程序import java.util.*;
import java.io.*;
public class ProcessRunner {
public static void main(String[] args) {
try {
Scanner s = new Scanner(Runtime.getRuntime().exec("python test.py").getInputStream()).useDelimiter("\A");
System.out.println(s.next());
}
catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
根据运行命令,
java ProcessRunner
我无法将正确格式的值 'n' 传递给 Python 程序,而且 java 运行 挂起。处理这种情况并从 java 程序内部将值动态传递给 'n' 到 python 程序的正确方法是什么?
raw_input()
, or input()
in Python 3,将阻塞等待标准输入上的新行终止输入,但是,Java 程序不会发送任何内容。
尝试使用 getOutputStream()
返回的流写入 Python 子进程。这是一个例子:
import java.util.*;
import java.io.*;
public class ProcessRunner {
public static void main(String[] args) {
try {
Process p = Runtime.getRuntime().exec("python test.py");
Scanner s = new Scanner(p.getInputStream());
PrintWriter toChild = new PrintWriter(p.getOutputStream());
toChild.println("1234"); // write to child's stdin
toChild.close(); // or you can use toChild.flush()
System.out.println(s.next());
}
catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
另一种方法是将 n
作为命令行参数传递。这需要修改 Python 脚本以预期和处理命令行参数,并修改 Java 代码以发送参数:
import java.util.*;
import java.io.*;
public class ProcessRunner {
public static void main(String[] args) {
try {
int n = 1234;
Process p = Runtime.getRuntime().exec("python test.py " + n);
Scanner s = new Scanner(p.getInputStream());
System.out.println(s.next());
}
catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
和 Python 脚本,test.py
:
import sys
if len(sys.argv) > 1:
print int(sys.argv[1])
如果我理解正确的话,你希望你的 java 程序将你的 python 脚本的任何输出传递给 System.out,并将你的 java 程序的任何输入传递给你的python 脚本,对吗?
查看以下程序以了解如何执行此操作。
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class ProcessRunner {
public static void main(String[] args) {
try {
final Process process = Runtime.getRuntime().exec("/bin/sh");
try (
final InputStream inputStream = process.getInputStream();
final InputStream errorStream = process.getErrorStream();
final OutputStream outputStream = process.getOutputStream()
) {
while (process.isAlive()) {
forwardOneByte(inputStream, System.out);
forwardOneByte(errorStream, System.err);
forwardOneByte(System.in, outputStream);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static void forwardOneByte(final InputStream inputStream,
final OutputStream outputStream)
throws IOException {
if(inputStream.available() <= 0) {
return;
}
final int b = inputStream.read();
if(b != -1) {
outputStream.write(b);
outputStream.flush();
}
}
}
注意这段代码只是一个概念演示。它会耗尽您的 cpu 并且无法处理更大的吞吐量。