Java Process“管道已经结束”的问题

时间:2010-03-08 08:44:16

标签: java process

我正在使用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)

对此有任何建议将不胜感激。

2 个答案:

答案 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.

解决这个问题解决了这个问题。