我启动一个cmd应用程序,该应用程序通过这个SyncPipe Runnable输出到System.out:
public class SyncPipe implements Runnable {
private final InputStream is;
private final OutputStream os;
public SyncPipe(InputStream is, OutputStream os) {
this.is = is;
this.os = os;
}
public void run() {
try {
final byte[] buffer = new byte[1024];
for ( int length = 0; ( length = is.read(buffer) ) != -1; )
os.write(buffer, 0, length);
System.out.print("stopped");
} catch ( Exception ex ) {
ex.printStackTrace();
}
}
}
我用cmd = "C:/bin/read.exe -f D:/test.jpg"
启动 RunIt
private class RunIt implements Runnable {
public int p;
public String cmd;
public RunIt (int p, String cmd) {
this.p = p;
this.cmd = cmd;
}
public void run() {
ProcessBuilder pb = new ProcessBuilder("cmd");
try {
process = pb.start();
(new Thread(new SyncPipe(process.getErrorStream(), System.err))).start();
(new Thread(new SyncPipe(process.getInputStream(), System.out))).start();
OutputStream out = process.getOutputStream();
out.write((cmd + "rn").getBytes());
out.flush();
out.close();
try {
process.waitFor();
} catch ( InterruptedException e ) {
e.printStackTrace();
}
println("Stopped using %d.", p);
} catch ( IOException ex ) {
ex.printStackTrace();
}
}
}
我现在的问题:我怎样才能(new Thread(new SyncPipe(process.getErrorStream(), System.err)))
死? 给 SyncPipe 一个布尔变量stop
,在运行时将其设置为true
,并通过for ( int length = 0; ( length = is.read(buffer) ) != -1 && !stop; )
检查它并没有解决问题。
提前非常感谢。
我最终做了@Gray建议的解决方法。 它现在可以工作:
public void run() {
try {
final byte[] buffer = new byte[1024];
do
if ( is.available() > 0 ) {
int length = is.read(buffer);
if ( length != -1 )
os.write(buffer, 0, length);
else
stop = true;
}
while ( !stop );
} catch ( Exception ex ) {
ex.printStackTrace();
}
}
线程将读取 EOS 并在底层进程退出时退出。你不必自己做任何特别的事情。
编辑在我看来,从阅读您的评论到其他答案,您的真正问题正在结束该过程。一旦发生这种情况,这些线程就会解开。你攻击了错误的一端。
>InputStream#read()
状态
此方法阻止,直到输入数据可用,结束 检测到流,或引发异常。
因此,当您进入for
循环时
for ( int length = 0; ( length = is.read(buffer) ) != -1; )
os.write(buffer, 0, length);
在到达流的末尾之前,它将无法退出,即进程停止或您自己关闭流。
如果SyncPipe
的全部目的是将内容传递到标准输出/错误流,为什么要停止运行它的Thread
?
我现在的问题:我怎样才能(new Thread(new SyncPipe(process.getErrorStream((, System.err(((死?
我相信你将不得不从它下面关闭输入流。 我怀疑它在读取中被阻止,并且没有stop
变量的设置(即使正确volatile
(也不会让读取线程解锁。
您将需要执行以下操作:
InputStream is = process.getInputStream();
InputStream es = process.getErrorStream();
...
is.close();
es.close();
代码大致如下所示。 我不确定您的waitFor()
电话是否返回。
InputStream is = process.getInputStream();
InputStream es = process.getErrorStream();
(new Thread(new SyncPipe(es, System.err))).start();
(new Thread(new SyncPipe(is, System.out))).start();
try {
OutputStream out = process.getOutputStream();
out.write((cmd + "rn").getBytes());
out.flush();
out.close();
try {
process.waitFor();
} catch ( InterruptedException e ) {
e.printStackTrace();
}
} finally {
is.close();
es.close();
}
另一个答案可能是在InputStream
上使用 available()
方法,以便您可以循环并检查您的stop
标志。 看到这个答案: https://stackoverflow.com/a/1089079/179850