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

发布于 2024-10-01 06:21:19 字数 1553 浏览 6 评论 0原文

(我是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();

,第一次尝试仅适用于 \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()

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

朕就是辣么酷 2024-10-08 06:21:19

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

一旦我从 Java 得到的行中 strip() 了额外的 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()

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()
忆离笙 2024-10-08 06:21:19

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

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文