写入java子进程

写入java子进程,java,subprocess,java.util.scanner,printwriter,printstream,Java,Subprocess,Java.util.scanner,Printwriter,Printstream,我正在尝试写入子流程的stdin(两者都是java应用程序)。读取进程的输出工作正常,但使用PrintStream或PrintWriter输入都不起作用。下面是我编写的一个示例程序,用于测试这种奇怪的行为,运行时没有参数。然后作为子进程运行相同的程序。子进程只是读取输入并将其回送到输出中。主进程获取stdin并将其写入子进程输入,然后将子进程输出输出到stdout 问题是,这不起作用。子进程的nextLine()与父进程中的println()语句不匹配,因此子进程从不输出任何内容 为什么会发生这

我正在尝试写入子流程的stdin(两者都是java应用程序)。读取进程的输出工作正常,但使用
PrintStream
PrintWriter
输入都不起作用。下面是我编写的一个示例程序,用于测试这种奇怪的行为,运行时没有参数。然后作为子进程运行相同的程序。子进程只是读取输入并将其回送到输出中。主进程获取stdin并将其写入子进程输入,然后将子进程输出输出到stdout

问题是,这不起作用。子进程的
nextLine()
与父进程中的
println()
语句不匹配,因此子进程从不输出任何内容

为什么会发生这种情况,以及我如何修复它(最好是在父进程上,因为我不能更改主项目的子进程)


这类事情的常见原因是缓冲问题

在您的示例程序中,我看到了一个可能的问题:在子进程中,您正在执行
System.out.println()
,但之后没有刷新。查阅Javadoc表明,
PrintStream
s可以自动刷新,但是没有指定默认的
System.out
是否是这样配置的,因此值得一试

请注意,一些平台决定仅在stdout是终端时自动刷新它(我不知道Java
System
是否会),这可能会在调试时混淆问题


(我注意到您说过在实际情况下不能更改子进程,但如果这就是问题所在,那么您必须更改子进程(或者,如果存在is-a-terminal测试,则将其包装在伪终端中)。

这类事情的常见原因是缓冲问题

在您的示例程序中,我看到了一个可能的问题:在子进程中,您正在执行
System.out.println()
,但之后没有刷新。查阅Javadoc表明,
PrintStream
s可以自动刷新,但是没有指定默认的
System.out
是否是这样配置的,因此值得一试

请注意,一些平台决定仅在stdout是终端时自动刷新它(我不知道Java
System
是否会),这可能会在调试时混淆问题


(我注意到您说过在实际情况下不能更改子进程,但如果问题是这样的,那么您必须更改子进程(或者,如果存在is-a-terminal测试,则将其包装在伪终端中)。

Java中的进程处理相当笨拙。您能直接在父进程中运行子进程的
main
方法吗?Java中的进程处理相当笨拙。你能直接在父进程中运行子进程的
main
方法吗?不过这是一件奇怪的事情。我还没有在这个示例程序上进行测试,但是在我正在处理的主项目上,父进程仍然拾取子进程的输出,但是当父进程尝试与子进程通信时,子进程没有响应。父级PrintWriter的刷新/不刷新是否会导致出现问题?父级代码正在刷新,因此应该可以。对于正确性来说,从来没有过多的刷新(好吧,除非接收者错误地读取了可用的内容,并且错误地假设它是一个完整的行/包/消息,这是不正确的,并且在负载下容易失败)。然而,这是一件奇怪的事情。我还没有在这个示例程序上进行测试,但是在我正在处理的主项目上,父进程仍然拾取子进程的输出,但是当父进程尝试与子进程通信时,子进程没有响应。父级PrintWriter的刷新/不刷新是否会导致出现问题?父级代码正在刷新,因此应该可以。对于正确性来说,从来没有过多的刷新(好吧,除非接收者错误地读取了可用的内容,并且错误地假设它是一个完整的行/包/消息,这是不正确的,并且在负载下容易失败)。
import java.lang.*;
import java.io.*;
import java.util.Scanner;

public class ProcTest{
    public static Scanner stdin;
    public static String line;
    public static Process sub;

    public static BufferedReader childout;
    public static PrintWriter childin;

    public static void main(String[] args){
            stdin = new Scanner(System.in);
            if(args.length > 0 && args[0].equals("y")){
                    while(true){
                            line = stdin.nextLine();
                            System.out.println(line);
                    }
            }else{
                    try{
                            sub = Runtime.getRuntime().exec("java ProcTest y");
                            childout = new BufferedReader(new InputStreamReader(sub.getInputStream()));
                            childin = new PrintWriter(sub.getOutputStream());
                            while(true){
                                    childin.println(stdin.nextLine());
                                    childin.flush();
                                    while(childout.ready()) System.out.println( childout.readLine() );
                            }
                    }catch(IOException e){
                            e.printStackTrace();
                    }
            }
    }
}