【发布时间】:2018-07-26 10:04:52
【问题描述】:
在命令行的 JavaFX 模型上工作时遇到了以下问题:
如果我运行一个运行另一个进程的进程(例如批处理文件)(例如使用简单的start notepad 打开记事本),我似乎无法正确确定批处理文件何时执行完毕:
-
Process#waitFor 已经在批处理文件启动时返回(我猜是因为我必须在可执行文件前面添加
cmd /c并且 cmd 确实在几分之一秒后完成) - 使用Process#getInputStream 读取输出仅在我关闭记事本后才结束,而不是在批处理文件终止后。
有没有我一直想念的方法?更重要的是:如果有的话,我如何确定通过cmd /c 产生的进程的结束?
可重现的例子:
example.bat:
@echo off
start notepad
REM You can change the path to something else but it should be something where tree produces a longer output to reproduce the problem.
cd %USERPROFILE%\Desktop
tree
Java代码:
import java.io.IOException;
import java.io.InputStream;
public class Main {
public static void main(String[] args) {
Process myProcess = null;
try {
myProcess = Runtime.getRuntime().exec("cmd /c C:\\Users\\geisterfurz007\\Desktop\\example.bat");
} catch (IOException e) {
e.printStackTrace();
}
startReadingThread(myProcess);
try {
myProcess.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Process ended");
}
private static void startReadingThread(Process myProcess) {
InputStream stream = myProcess.getInputStream();
new Thread(() -> {
int character;
try {
while ((character = stream.read()) != -1) {
System.out.write(character);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
System.out.println("Reading ended");
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
开始打印树,中间打印“进程结束”被写入控制台。最后,在我关闭记事本窗口后打印“阅读结束”。
我的目标是找到在记事本关闭时忽略树完成打印(即批处理文件完成处理)的点。
基于Leviands's answer,我尝试在进程流执行完成后关闭它,但无济于事。
不幸的是,InputStream 再次关闭了中间内容,而 ErrorStream(我也在实际应用程序中读过)不会关闭,从而阻塞了线程。
【问题讨论】:
标签: java multithreading process stream