我编写了一个简单的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”。
答案 0 :(得分: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
。这是一个明确的指标,表明该过程提前终止。
答案 1 :(得分:1)
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
是您的路径,这将有效,否则您将需要像您在示例中所做的那样提供可执行文件的完整路径;)