我正在使用Java Process API编写一个从网络接收二进制输入的类(比如通过TCP端口A),处理它并将二进制输出写入网络(比如通过TCP端口B)。我使用的是Windows XP。代码看起来像这样。有两个函数叫run()
和receive()
:run在启动时调用一次,而只要有通过网络接收的新输入就调用receive。从不同的线程调用运行和接收。
run进程启动exe并接收exe的输入和输出流。 Run还会启动一个新线程,将exe输出写入端口B.
public void run() {
try {
Process prc = // some exe is `start`ed using ProcessBuilder
OutputStream procStdIn = new BufferedOutputStream(prc.getOutputStream());
InputStream procStdOut = new BufferedInputStream(prc.getInputStream());
Thread t = new Thread(new ProcStdOutputToPort(procStdOut));
t.start();
prc.waitFor();
t.join();
procStdIn.close();
procStdOut.close();
} catch (Exception e) {
e.printStackTrace();
printError("Error : " + e.getMessage());
}
}
接收将收到的输入从端口A转发到exe。
public void receive(byte[] b) throws Exception {
procStdIn.write(b);
}
class ProcStdOutputToPort implements Runnable {
private BufferedInputStream bis;
public ProcStdOutputToPort(BufferedInputStream bis) {
this.bis = bis;
}
public void run() {
try {
int bytesRead;
int bufLen = 1024;
byte[] buffer = new byte[bufLen];
while ((bytesRead = bis.read(buffer)) != -1) {
// write output to the network
}
} catch (IOException ex) {
Logger.getLogger().log(Level.SEVERE, null, ex);
}
}
}
问题是我在receive()
内获得了以下堆栈,之后立即返回prc.waitfor()
。行号显示堆栈在写入exe时。
The pipe has been ended
java.io.IOException: The pipe has been ended
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:260)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:109)
at java.io.FilterOutputStream.write(FilterOutputStream.java:80)
at xxx.receive(xxx.java:86)
对此有任何建议将不胜感激。
答案 0 :(得分:1)
这意味着在另一端已关闭管道后,您正在写入管道。
这表示您的应用程序协议中存在重大错误。
答案 1 :(得分:0)
我最近遇到了同样的问题,我找到了解决方案。
首先,“管道已经结束”错误不是Java错误 - 它来自Windows系统。根据MSDN:
如果您正在尝试编写,则使用过程已关闭管道 在管道上,没有可用的读者。
信息量不大。但是,如果流程已关闭管道本身,则可能意味着流程中出现了一些错误。
要检查这一点,请将来自流程的错误重定向到例如文件:
File f = new File("errors.txt");
pb.redirectError(f);
在我的情况下(我一直在尝试执行SrcML解析器)文件包含:
.\libs\srcML-Win\src2srcml.exe: unrecognised option `--language Java'
Try 'src2srcml --help' for more information.
解决这个问题解决了这个问题。