java:如何通过管道读取和写入进程(stdin / stdout)

(我是java的新手)我需要启动一个进程并接收2个或3个句柄:对于STDIN,STDOUT,(和STDERR),所以我可以向进程写入输入并接收其输出,与命令行管道相同表现(例如“grep”)

在Python中,这是通过以下代码实现的:

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

什么是Java等价物?

到目前为止我已经尝试过了

 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第一次尝试仅适用于\ n \ n,但不适用于单\ n(为什么?)

以下代码有效,但所有输入都是事先给出的,而不是我正在寻找的行为:

 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 ); 

输出:

 response1: AAAAA response2: response3: bbbbbb response4: 

正在运行的进程看起来像这样:

 s = sys.stdin.readline() print s.upper() s = sys.stdin.readline() print s.lower() 

好吧,这也是我的python的代码错误,但与@ Jon的答案相反,有一个EXTRA换行符(确切地说是0xA0,这不是Windows的标准)。

一旦我从Java中获取了额外的0xA0,python就会在回来的路上为Java添加一个“正常”\ n,并且事情顺利进行。

为了问题和答案的完整性,这是一个有效的Java代码:

 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(); } } } 

这是python代码

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

我相信问题出在你正在调用的过程中:

 s = sys.stdin.readline() print s.upper() s = sys.stdin.readline() print s.lower() 

我怀疑readline将读取该行,但s包括行终止符。 然后你打印那行,但是没有行终止符 ……然后Java就会阻塞,直到它读取一个行终止符,它将永远阻塞,因为进程没有给出。

这是一个小小的猜测,因为我不清楚你所调用的语言是什么语言 – 如果print实际上输出了一个行终止符,那么这是一个不正确的猜测。 但是,如果没有,您可能需要将其更改为:

 s = sys.stdin.readline() println s.upper() s = sys.stdin.readline() println s.lower() 

编辑:这并没有解释样本输出中的空白行…不知道发生了什么,真的,但不幸的是我现在无法调查。