代码之家  ›  专栏  ›  技术社区  ›  Berry Tsakala

JAVA:如何同时读取和写入进程管道(STDIN/STDUT)

  •  4
  • Berry Tsakala  · 技术社区  · 14 年前

    (我是爪哇新手) 我需要启动一个进程并接收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()
    
    2 回复  |  直到 14 年前
        1
  •  9
  •   Berry Tsakala    14 年前

    好吧,这也是我的python的代码错误,但是与@jon的答案相反,这里有一个额外的换行符(准确地说是0xa0,这不是windows的标准)。

    一旦我从Java中得到的一行额外的0xA0,Python在返回的过程中添加一个“正常”\n到Java,并且运行顺利。

    对于问题和答案的完整性,这里有一个工作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()
    
        2
  •  2
  •   Jon Skeet    14 年前

    我相信问题就在你打电话的过程中:

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

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

    这只是一个小小的猜测,因为我不太清楚你所称的过程使用的语言是什么-if print 事实上 输出一个行终止符,那么这是一个错误的猜测。但是,如果没有,您可能需要将其更改为如下内容:

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

    编辑:这不能解释示例输出中的空行…不知道发生了什么,真的,但不幸的是我现在不能调查。