(i'm new to java) I need to start a process and receive 2 or 3 handles: for STDIN, STDOUT, (and STDERR), so I can write input to the process and receive its output, the same way command line pipes behave (e.g. "grep")
in Python this is acheived with the following code:
from subprocess import Popen, PIPE
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE)
(child_stdin, child_stdout) = (p.stdin, p.stdout)
child_stdin.write('Yoram Opposum\n')
child_stdin.flush()
child_stdout.readlines()
What's the Java equivalent??
I've tried so far
Process p = Runtime.getRuntime().exec(cmd);
BufferedReader inp = new BufferedReader( new InputStreamReader(p.getInputStream()) );
BufferedWriter out = new BufferedWriter( new OutputStreamWriter(p.getOutputStream()) );
out.write( "Some Text!\n\n" );
out.flush();
line = inp.readLine();
print("response1: " + line ); // that's ok
out.write( "Second Line...\n" );
out.flush();
line = inp.readLine();
print("response2: " + line ); // returns an empty string, if it returns,,,
inp.close();
out.close();
BTW the first try works only with \n\n, but doesn't work with single \n (why?)
the following code works, but all input is given in advance, not the behavior i'm looking for:
out.write( "Aaaaa\nBbbbbb\nCcccc\n" );
out.flush();
line = inp.readLine();
print("response1: " + line );
line = inp.readLine();
print("response2: " + line );
line = inp.readLine();
print("response3: " + line );
line = inp.readLine();
print("response4: " + line );
output:
response1: AAAAA
response2:
response3: bbbbbb
response4:
the process being run looks like that:
s = sys.stdin.readline()
print s.upper()
s = sys.stdin.readline()
print s.lower()
You can't open the same file to read and write at the same time. You have to open and save the file information in a data structure and then close it. Then you have to work with the data structure in memory and open the file to write results. And when you finish to write you should close it.
To write one specified character to an output stream, use the write method with one int parameter. The int parameter represents the character to write. We can use what we have learned to read from one file and simultaneously write to another, as demonstrated in Listing C.
And here are some classes you can use to write character data to a file: Writer: This is an abstract class to write the character streams. OutputStreamWriter: This class is used to write character streams and also convert them to byte streams. FileWriter: A class to actually write characters to the file.
ok, it was also my python's code fault, but opposite to @Jon's answer, there was an EXTRA newline (0xA0 to be exact, which isn't Windows' standard).
once i'm strip()ing the extra 0xA0 from the line i get from Java, python adds a single "normal" \n to Java on the way back, and things run smoothly.
for the completeness of the question and answer, here's a working Java code:
import java.io.*;
import java.util.*;
public class Main {
public static BufferedReader inp;
public static BufferedWriter out;
public static void print(String s) {
System.out.println(s);
}
public static String pipe(String msg) {
String ret;
try {
out.write( msg + "\n" );
out.flush();
ret = inp.readLine();
return ret;
}
catch (Exception err) {
}
return "";
}
public static void main(String[] args) {
String s;
String cmd = "c:\\programs\\python\\python.exe d:\\a.py";
try {
print(cmd);
print(System.getProperty("user.dir"));
Process p = Runtime.getRuntime().exec(cmd);
inp = new BufferedReader( new InputStreamReader(p.getInputStream()) );
out = new BufferedWriter( new OutputStreamWriter(p.getOutputStream()) );
print( pipe("AAAaaa") );
print( pipe("RoteM") );
pipe("quit")
inp.close();
out.close();
}
catch (Exception err) {
err.printStackTrace();
}
}
}
and this is the python code
import sys
s = sys.stdin.readline().strip()
while s not in ['break', 'quit']:
sys.stdout.write(s.upper() + '\n')
sys.stdout.flush()
s = sys.stdin.readline().strip()
I believe the problem is in the process you're calling:
s = sys.stdin.readline()
print s.upper()
s = sys.stdin.readline()
print s.lower()
I suspect that readline
is going to read the line but s
will not include the line terminator. You're then printing that line, but without a line terminator... Java is then blocking until it reads a line terminator, which will block forever as the process isn't giving one.
This is all a bit of a guess as it's not exactly clear to me what language your called process is in - if print
actually does output a line terminator, then it's an incorrect guess. However, if not, you may need to change it to something like:
s = sys.stdin.readline()
println s.upper()
s = sys.stdin.readline()
println s.lower()
EDIT: That doesn't explain the blank lines in sample output... no idea what's going on, really, but unfortunately I can't look into it now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With