我的目标:
当我从命令行运行Python(CPython)时(不是Jython,因为它不支持像NumPy这样的软件包)我可以交互式地编写代码行并从输出中查看结果。
我的目标是在JAVA中以编程方式执行此操作。我试图这样做:
代码:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class PythonProcess {
private Process proc;
private BufferedReader stdInput;
private BufferedReader stdError;
private BufferedWriter stdOutput;
public PythonProcess() {
Runtime rt = Runtime.getRuntime();
String[] commands = { "python.exe" };
try {
proc = rt.exec(commands);
stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
stdOutput = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
private String executeCommand(String command) throws IOException {
stdOutput.write(command + "\n");
stdOutput.newLine();
String s = null;
StringBuffer str = new StringBuffer();
while ((s = stdInput.readLine()) != null) {
str.append(s);
}
return str.toString();
}
public void initialize() throws IOException {
// will create a file - if correctly executed in python
stdOutput.write("f = open('c:/downloads/deleteme.txt','w')");
stdOutput.newLine();
stdOutput.write("f.write('hi there, I am Python \n')");
stdOutput.newLine();
stdOutput.write("f.close()");
stdOutput.newLine();
stdOutput.flush();
}
public static void main(String[] args) throws IOException {
PythonProcess proc = new PythonProcess();
proc.initialize(); // time demanding initialization
for (int i = 0; i < 10; i++) {
String out = proc.executeCommand("print \"Hello from command line #"+i+"\"");
System.out.println("Output: " + out);
}
}
}
问题:
由于未创建文件c:/downloads/deleteme.txt,因此似乎Python中不执行 stdOutput 在initialize()方法中传递的代码。稍后,当调用 executeCommand 方法时,我也无法读取 stdInput 的任何输出。
问题:
BTW1:Jython不是要走的路,因为我需要执行python不支持的CPython指令。
BTW2:我知道我可以通过String [] commands = {&#34; python.exe&#34;以非交互方式执行python脚本&#34; script.py&#34;} ;.问题是当初始化花费大量时间时,这将意味着重大的性能问题。
答案 0 :(得分:0)
遗憾的是,无法与Python进程直接交互。而不是使用TCP套接字的解决方案:
<强> PythonServer.java 强>
package pythonexample;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class PythonServer {
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder ps=new ProcessBuilder("python.exe","tcpServer.py");
ps.redirectErrorStream(true);
System.out.println("Starting Python server.");
Process pr = ps.start();
BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
pr.waitFor();
in.close();
System.exit(0);
}
}
<强> tcpServer.py 强>
import socket
# DO INITIALIZATION
TCP_IP = '127.0.0.1'
TCP_PORT = 5006
BUFFER_SIZE = 20 # Normally 1024, shorter if we want fast response
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
while 1:
print 'Waiting for connection'
conn, addr = s.accept()
print 'Connection address:', addr
if addr[0] == '127.0.0.1': # security - only local processes can connect
data = conn.recv(BUFFER_SIZE)
print "received data:", data
res = eval(data)
print "Sending result:", res
conn.send("This is reply from Python " + str(res) + "\n")
conn.close()
<强> PythonClient.java 强>
package pythonexample;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class PythonClient {
public static void main(String[] args) throws IOException {
String serverAddress = "127.0.0.1";
Socket s = new Socket(serverAddress, 5006);
// do this in loop if needed
String result = sendCommand(s, "1+1 \n");
System.out.println("Received result: "+result);
// closing socket
s.close();
}
private static String sendCommand(Socket s, String command) throws IOException {
BufferedWriter ouput = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
ouput.write(command);
ouput.flush();
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
String answer = input.readLine();
return answer;
}
}
首先执行PythonServer类,初始化服务器。然后执行将数据发送到服务器并获取结果的PythonClient。
当然所有功能,如NumPy和其他功能,例如,不支持Jython现已上市。