读取子进程的输出中断

时间:2014-05-16 13:24:00

标签: java process pipe

我想启动子进程并读取其输出直到EOF或直到内部标志被清除。

我的第一次尝试是在另一个线程中调用InputStream.close(),但是虽然它适用于套接字,但它不能使用Process.getInputStream()的结果:主线程仍在等待{ {1}}和杀手线程挂起read()(窗口)或继续无效(linux)。

然后我尝试检查close0(),但它没有检测到EOF:它返回0.

InputStream.available()

我最后的希望是从返回的流中窃取频道并使用nio

1 个答案:

答案 0 :(得分:0)

在Windows中,此命令不会终止。

 cmd = new String[] { "cmd", "/c", "more & more" };

而不是尝试这个简单的命令

 cmd = new String[] { "cmd", "/c", "dir" };

如果你想阅读你的流

public static void slurp(final InputStream is, final int bufferSize)
    {
        try(final Reader in = new InputStreamReader(is, "UTF-8");
                BufferedReader br = new BufferedReader(in);){
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

通过像这样传递流来调用此方法。

final BbbTest bbTest = new BbbTest();
    Thread t = new Thread("xsdfds") {
                @Override
                public void run() {
                    try {
                        slurp(bbTest.getStream());
                    } catch (RuntimeException e) {
                        throw e;
                    } catch (Exception e) {
                        throw new RuntimeException ( );
                    }
                }
            };
            t.start();

如果要从子线程中终止进程。 像BbbTest一样为Process创建setter和getter方法

public class BbbTest {

    private Process proc;

    /**
     * @return the proc
     */
    public Process getProc() {
        return proc;
    }

    /**
     * @param proc the proc to set
     */
    public void setProc(Process proc) {
        this.proc = proc;
    }
        private InputStream getStream() throws IOException {
        String[] cmd;
        if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
            //  cmd = new String[] { "cmd", "/c", "more & more" };
            cmd = new String[] { "cmd", "/c", "dir" };
        } else {
            cmd = new String[] { "sh", "-c", "cat; cat" };
        }
        proc = Runtime.getRuntime().exec(cmd);
        return proc.getInputStream();
    }
}

现在使用过程可以销毁

bbTest.getProc().destroy();

如果要基于其他流的输出终止进程,可以通过检查行内容并使用destroy

终止以slurp方法添加逻辑
UPDATE

简单演示

public class BbbTest {


    private Process startProcess(String[] commands) throws IOException {
        Process proc = Runtime.getRuntime().exec(commands);
        return proc;
    }

    public static void slurp(final InputStream is)
    {
        try(final Reader in = new InputStreamReader(is, "UTF-8");
                BufferedReader br = new BufferedReader(in);){
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
                if (line.equals("end")){
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String args[]) throws Exception {
        final BbbTest bbTest = new BbbTest();
        final Process process = bbTest.startProcess(new String[] { "cmd", "/c", "more" });
        Thread t = new Thread("xsdfds") {
            @Override
            public void run() {
                try {
                    slurp(process.getInputStream());
                    process.destroy();
                } catch (RuntimeException e) {
                    throw e;
                } catch (Exception e) {
                    throw new RuntimeException ( );
                }
            }
        };
        t.start();

        try(OutputStream out = process.getOutputStream();
                BufferedOutputStream outStream = new BufferedOutputStream(out);){
            outStream.write("Test".getBytes());
            outStream.write("\n".getBytes());
            outStream.write("end".getBytes());
            outStream.write("\n".getBytes());
            outStream.flush();
        }


    }
}

看看这个示例:您应该有一些条件来终止子线程(读取prcoess),就像流写入"结束" /或EOF结束(处理关闭输入流)