My Objective:
When I run Python (CPython) from command line (not Jython since it does not support some packages like NumPy) I can interactively write lines of code and see results from its output.
My objective is to do this programmatically in JAVA. Here is my attempt to do so:
Code:
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);
}
}
}
Problem:
It seems that the code passed by stdOutput in initialize() method is not executed by Python at all since the file c:/downloads/deleteme.txt was not created. Later on I am also unable to read any output from the stdInput when calling executeCommand method.
Questions:
- Is there any simple way how to fix the code?
- Can anyone point me to some example how can I interact with python e.g. by client - server way
- or Any other idea?
BTW1: Jython is not the way to go since I need to execute CPython directives that are not supported by python.
BTW2: I know that I can execute the python script in noninteractive way by String[] commands = { "python.exe" "script.py"};. The issue is when the initilaization takes significant time it would mean significant performance issue.