【问题标题】:PipedInputStream, PipedOutputStream and ProcessPipedInputStream、PipedOutputStream 和流程
【发布时间】:2014-03-24 15:53:04
【问题描述】:

我正在学习 java PipedInputStream/PipeOutputStream 。

我想阅读标准输入(下面的 'Source' 类)并将其重定向到一个进程(这里是 'grep A'),即 Grep 的输出将被重定向到 System.out。

为了在 grep 之后使用 stdout 和 stderr,我还创建了一个类 CopyTo 来将输入流重定向到输出流。

import java.io.*;
class Test
    {
    private static class Source
        implements Runnable
        {
        private PipedOutputStream pipedOutputStream=new PipedOutputStream();
        private InputStream in;

            Source(InputStream in) throws IOException
                {
                this.in=in;
                }


            @Override
            public void run()
                {
                try
                    {
                    int c;
                    while((c=this.in.read())!=-1)
                        {
                        pipedOutputStream.write(c);
                        }
                    pipedOutputStream.flush();
                    pipedOutputStream.close();
                    }
            catch(Exception err)
                {
                err.printStackTrace();
                }
                }
        }

    private static class Grep
        implements Runnable
        {

        private PipedInputStream pipeInPipedInputStream;

        public Grep(Source src) throws IOException
            {
            this.pipeInPipedInputStream=new PipedInputStream(src.pipedOutputStream);
            }

            @Override
            public void run()
                {
            try {
                Process proc=Runtime.getRuntime().exec(new String[]{
                    "/bin/grep",
                    "A"});
                OutputStream os=proc.getOutputStream();


                Thread t1=new Thread(new CopyTo(proc.getErrorStream(),System.err));
                Thread t2=new Thread(new CopyTo(proc.getInputStream(),System.out));
                t1.start();
                t2.start();
                int c;
                while((c=this.pipeInPipedInputStream.read())!=-1)
                    {   
                    os.write((char)c);
                    }

                t1.join();
                t2.join();
                } 
            catch (Exception e) {
                e.printStackTrace();
                }
                }
        }

    private static class CopyTo implements Runnable
        {
        private InputStream in;
        private OutputStream out;
        CopyTo(InputStream in,OutputStream out)
            {
            this.in=in;
            this.out=out;
            }
        @Override
        public void run() {
            try {
                int c;
                while((c=in.read())!=-1)
                    {
                    out.write(c);
                    }
                }
            catch (Exception e)
                {
                e.printStackTrace();
                }
            }
        }


    public static void main(String[] args)
        {
        try
            {
            Source src=new Source(System.in);
            Thread t1=new Thread(src);
            Thread t2=new Thread(new Grep(src));
            t1.start();
            t2.start();
            }
        catch(Exception err)
            {
            err.printStackTrace();
            }
        }

    }

但是,编译和运行程序不会产生任何输出(并且程序被冻结)。

$ javac Test.java && echo -e "A\nT\nG\nC" | java Test

我哪里错了?谢谢。

【问题讨论】:

    标签: java multithreading process pipe java.util.concurrent


    【解决方案1】:

    您只需要在代码块之后的 Grep 类的 run() 方法中刷新和关闭 os 流:

    while((c=this.pipeInPipedInputStream.read())!=-1)
    {   
        os.write((char)c);
    }
    

    添加以下行:

    os.flush();
    os.close();
    

    你的 Grep 类的 run() 方法必须是这样的:

    @Override
    public void run()
    {
        try {
            Process proc=Runtime.getRuntime().exec(new String[]{
                 "/bin/grep",
                 "A"});
            OutputStream os=proc.getOutputStream();
    
            Thread t1=new Thread(new CopyTo(proc.getErrorStream(),System.err));
            Thread t2=new Thread(new CopyTo(proc.getInputStream(),System.out));
            t1.start();
            t2.start();
            int c;
            while((c=this.pipeInPipedInputStream.read())!=-1)
            {   
                 os.write((char)c);
            }
    
            //missing lines of code
            os.flush();
            os.close();
    
            t1.join();
            t2.join();
        } 
        catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    命令的输出:

    $ javac Test.java && echo -e "A\nT\nG\nC" | java Test
    

    将是:

    A
    

    程序将终止。

    【讨论】:

      猜你喜欢
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-18
      • 2017-10-28
      • 2014-07-21
      • 1970-01-01
      • 2018-10-06
      • 1970-01-01
      相关资源
      最近更新 更多