如何在此java程序中读取另一个java程序的std输出?

如何在此java程序中读取另一个java程序的std输出?,java,command-line,std,Java,Command Line,Std,我编写了一个简单的Java程序,它只需每隔5秒向std输出一些“hello” public class DDD { public static void main(String[] args) throws InterruptedException { for (int i = 0; ; i++) { System.out.println("hello " + i); Thread.sleep(5000);

我编写了一个简单的Java程序,它只需每隔5秒向std输出一些“hello”

public class DDD {
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; ; i++) {
            System.out.println("hello " + i);
            Thread.sleep(5000);
        }
    }
}
然后我编译它并得到一个.class

我编写了另一个java程序来运行它并获得输出:

public static void main(String[] args) throws Exception {
    String command = "c:\\java\\jdk1.7.0_07\\bin\\java mytest.DDD";
    Process exec = Runtime.getRuntime().exec(command);

    BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getInputStream()));
    while (true) {
        String line = reader.readLine();
        System.out.println(line);
        if (line == null) {
            Thread.sleep(1000);
        }
    }
}
但它总是打印:

null
null
null
null
null
null
null

哪里错了?我的操作系统是“windows XP”。

首先,你的程序完全正确。我的意思是,启动流程和读取输入流的方式应该有效。让我们来看看为什么没有

我运行了你的程序,遇到了同样的行为。为了理解它为什么不起作用,我做了一个简单的改变:我没有阅读
getInputStream()
,而是听了
getErrorStream()
。这样,我就可以看到
java
命令是否返回了错误,而不是启动程序。果然,它打印了以下信息:

Error: Could not find or load main class myTest.DDD
就是这样,我想你也是这样。程序无法找到DDD类,因为它不在类路径中

我在Eclipse中工作,类被编译到项目中的目录
bin
,因此我只是将命令改为

String command = "c:\\java\\jdk1.7.0_07\\bin\\java -cp bin mytest.DDD";
它成功了。我获得(切换回getInputStream()后):

这意味着默认情况下,由命令
exec
生成的进程的工作目录是项目的根目录,而不是编译类的目录

总之,只需指定类路径,它就可以正常工作。如果不是,请查看错误流包含的内容

注意:您可能已经猜到了原因:Javadoc指定
readline()
返回
null
,如果已经到达流的末尾。很明显,进程提前终止。

BufferedReader#readLine
到达流末尾时将返回
null

因为您基本上忽略了这个退出指示器,并在一个无限循环中循环,所以您得到的只是
null

可能的原因是进程向错误流输出了一些错误信息,而您没有读取这些信息

您应该尝试改用
ProcessBuilder
,它允许您将错误流重定向到输入流中

try {
    String[] command = {"java.exe", "mytest.DDD"};
    ProcessBuilder pb = new ProcessBuilder(command);
    // Use this if the place you are running from (start context)
    // is not the same location as the top level of your classes
    //pb.directory(new File("\path\to\your\classes"));
    pb.redirectErrorStream(true);
    Process exec = pb.start();

    BufferedReader br = new BufferedReader(new InputStreamReader(exec.getInputStream()));
    String text = null;
    while ((text = br.readLine()) != null) {
        System.out.println(text);
    }
} catch (IOException exp) {
    exp.printStackTrace();
}

ps-如果
java.exe
是您的路径,那么这将起作用,否则您将需要提供可执行文件的完整路径,就像您在示例中所做的那样;)

主要原因是它到达了输入流的末尾。这表明进程失败,并已将原因写入错误流,但您没有读取它。
try {
    String[] command = {"java.exe", "mytest.DDD"};
    ProcessBuilder pb = new ProcessBuilder(command);
    // Use this if the place you are running from (start context)
    // is not the same location as the top level of your classes
    //pb.directory(new File("\path\to\your\classes"));
    pb.redirectErrorStream(true);
    Process exec = pb.start();

    BufferedReader br = new BufferedReader(new InputStreamReader(exec.getInputStream()));
    String text = null;
    while ((text = br.readLine()) != null) {
        System.out.println(text);
    }
} catch (IOException exp) {
    exp.printStackTrace();
}