使用命令行的JavaFX样机时,我遇到了以下问题:
如果我运行一个进程(例如批处理文件),而该进程又运行另一个进程(例如用简单的width: calc((99% - 2 * #{$gutter-horizontal}) / 3);
打开记事本),我似乎无法正确确定批处理文件何时完成执行:
start notepad
,而cmd确实在一秒钟内就完成了)我是否一直缺少一种方法?而且更重要的是:如何确定cmd /c
产生的过程的结束?
可复制的示例:
example.bat:
cmd /c
JavaCode:
@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
开始打印树,并且在中间打印“处理结束”被写入控制台。最后,在我关闭记事本窗口后,打印出“阅读结束”。
我的目标是忽略记事本的关闭时间,找到树已完成打印(即批处理文件已完成处理)的位置。
基于Leviands's answer,我尝试在完成执行后无济于事地关闭“流程”流。
不幸的是,InputStream再次关闭了中间内容,ErrorStream(我也在实际应用程序中阅读过)也没有关闭,因此阻塞了线程。
答案 0 :(得分:2)
首先,非常感谢Leviand在他们的InputStream#available中提到answer,这使我得到了一些切实可行的东西:
这个想法是,在我正在寻找的时间点上,Process#isAlive应该返回false,因为Stream需要比Process进程更长的时间来处理(如果有意义),而InputStream不应读取任何字符。 ,因此InputStream#available应该返回0。
这导致这段代码:
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).start();
}
private static Thread startReadingThread(Process myProcess) {
InputStream stream = myProcess.getInputStream();
return new Thread(() -> {
int character;
try {
while (myProcess.isAlive() || stream.available() > 0) {
if ((character = stream.read()) == -1) {
break;
}
System.out.write(character);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
使用上面的代码,我可以忽略所有孙进程而从Processes流中进行读取。
一段时间后,有几件事要解决:
stream.available() > 0
必须替换为reader.ready()
。答案 1 :(得分:1)
您要启动startReadingThread(myProcess);
,然后用myProcess.waitFor();
告诉进程myProcess
结束,然后再打印System.out.println("Reading ended");
,这与您愿意执行的相反
应该“阻止”另一个人开始的过程是startReadingThread
。
该问题也出现在while循环中,这是不正确的。
我会做出类似的更改(不确定stream.available() != 0
,但它正在测试中):
private static Thread startReadingThread(Process myProcess) {
InputStream stream = myProcess.getInputStream();
return new Thread(() -> {
int character;
try {
while (stream.available() != 0) {
if((character = stream.read()) == -1) {
System.out.write(character);
stream.close();
break;
}
System.out.write(character);
}
stream.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
System.out.println("Reading ended");
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
然后使用以下命令编辑主文件:
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();
}
try {
if(myProcess.waitFor() == 0){
startReadingThread(myProcess).start();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Process ended");
输出(我来自意大利)
已连接到目标VM,地址:“ 127.0.0.1:56607”,传输: 'socket'过程已结束 卷OSDisk Numero序列号:12DA-8173 C:。非抗精神病药 sottocartelle
阅读结束:已与目标VM断开连接,地址: '127.0.0.1:56607',运输工具:'socket'
以退出代码0结束的过程
编辑: 这是对里面有子文件夹的文件夹的测试(我在屏幕快照中附加了奇怪符号的原因)
这是文件夹内容: