0

我编写了一个简单的 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”。

4

2 回答 2

1

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

我运行了你的程序,我遇到了同样的行为。为了理解为什么它不起作用,我做了一个简单的改变:我没有阅读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()后):

hello 0
hello 1
hello 2
hello 3

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

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

注意:您可能已经猜到原因:Javadoc 指定如果到达流的末尾则readline()返回。null这清楚地表明该过程已提前终止。

于 2013-11-14T03:30:04.417 回答
1

BufferedReader#readLinenull当它到达流的末尾时将返回。

因为您基本上忽略了这个退出指示器并在无限循环中循环,所以您得到的只是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是您的路径,这将起作用,否则您将需要提供可执行文件的完整路径,就像您在示例中所做的那样;)

于 2013-11-14T03:33:05.637 回答