Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
693 views
in Technique[技术] by (71.8m points)

java: how to both read and write to & from process thru pipe (stdin/stdout)

(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
')
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!

" );
out.flush();
line = inp.readLine();
print("response1: " + line );   // that's ok
out.write( "Second Line...
" );
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 , but doesn't work with single (why?)

the following code works, but all input is given in advance, not the behavior i'm looking for:

out.write( "Aaaaa
Bbbbbb
Ccccc
" );
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()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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" 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 + "
" );
        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() + '
')
    sys.stdout.flush()
    s = sys.stdin.readline().strip()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...