3

我正在开发一个包含 3 个按钮的 Java 桌面应用程序(我们称之为控制台):其中两个启动 Win32 应用程序;第三个应该启动一个可执行的 jar:

ProcessBuilder pb = new ProcessBuilder("java", "-jar", testDrivePath);
Process process = pb.start();

其中testDrivePath是 jar 的路径(类似于“C:\Programs\TestDrive.jar”)

TestDrive.jar 应用程序正确启动,但一段时间后它会阻塞并且无法进行任何操作。

如果我关闭控制台,TestDrive.jar 就会恢复工作!

如果我单独启动 TestDrive.jar(而不从控制台调用它),一切都是正确的。

任何人都可以建议吗?

4

1 回答 1

4

您可能需要从进程中读取输出流。您可以像这样获得 stdout 和 stderr 流:

InputStream stdout = process.getInputStream();
InputStream stderr = process.getErrorStream();

您可以创建工作线程以异步读取这些流。

Thread threadOut = new Thread( new MyInputStreamSink( stdout, "out" ));
Thread threadErr = new Thread( new MyInputStreamSink( stderr, "err" ));

threadOut.setDaemon(true);
threadErr.setDaemon(true);
threadOut.setName( String.format("stdout reader" ));
threadErr.setName( String.format("stderr reader" ));

threadOut.start();
threadErr.start();

这是使用流输出的 Runnable 的实现。

private static class MyInputStreamSink implements Runnable {
    private InputStream m_in;
    private String m_streamName;

    MyInputStreamSink( InputStream in, String streamName ) {
        m_in = in;
        m_streamName = streamName;
    }

    @Override
    public void run() {
        BufferedReader reader = null;
        Writer writer = null;

        try {
            reader = new BufferedReader( new InputStreamReader( m_in ) );

            for ( String line = null; ((line = reader.readLine()) != null); ) {
                // TODO: Do something with the output, maybe.
            }
        } catch (IOException e) {
            s_logger.log( Level.SEVERE, "Unexpected I/O exception reading from process.", e );
        }
        finally {
            try {
                if ( null != reader ) reader.close();
            }
            catch ( java.io.IOException e ) {
                s_logger.log( Level.SEVERE, "Unexpected I/O exception closing a stream.", e );
            }
        }
    }
}
于 2013-05-30T13:53:52.977 回答