Java IO: 管道

来源:互联网 发布:照片看图软件 编辑:程序博客网 时间:2024/06/13 22:24

通过管道 PipedInputStream和PipedOutputStream 可以实现不同线程之间的数据传输,使用很简单,先来看下简单的例子:

@Test    public void pipeTest() throws IOException, InterruptedException {        PipedOutputStream outputStream = new PipedOutputStream();        PipedInputStream inputStream = new PipedInputStream(outputStream);        new Thread(new Runnable() {            @Override            public void run() {                while (true) {                    try {                        outputStream.write("test".getBytes());                    } catch (IOException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    } finally {                    }                    try {                        Thread.sleep(1000 * 5);                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                }            }        }).start();        new Thread(new Runnable() {            @Override            public void run() {                try {                    while (true) {                        int len = inputStream.read();                        while (len != -1) {                            System.out.println((char) len);                            len = inputStream.read();                        }                    }                } catch (IOException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                } finally {                    try {                        inputStream.close();                    } catch (IOException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                }            }        }).start();        Thread.sleep(1000 * 100);    }

输出结果是 每隔5秒输出一个test

testtest

源码就简单说下:
通过PipedInputStream 的初始化或者connect 与PipedOutputStream 关联,当write时,其实就是调用input的方法,将write数据写入到input的buffer中

 synchronized void receive(byte b[], int off, int len)  throws IOException {        checkStateForReceive();        writeSide = Thread.currentThread();        int bytesToTransfer = len;        while (bytesToTransfer > 0) {            if (in == out)                awaitSpace();            int nextTransferAmount = 0;            if (out < in) {                nextTransferAmount = buffer.length - in;            } else if (in < out) {                if (in == -1) {                    in = out = 0;                    nextTransferAmount = buffer.length - in;                } else {                    nextTransferAmount = out - in;                }            }            if (nextTransferAmount > bytesToTransfer)                nextTransferAmount = bytesToTransfer;            assert(nextTransferAmount > 0);            //将b数据赋给buffer            System.arraycopy(b, off, buffer, in, nextTransferAmount);            bytesToTransfer -= nextTransferAmount;            off += nextTransferAmount;            in += nextTransferAmount;            if (in >= buffer.length) {                in = 0;            }        }    }

可以看到加了synchronized,所以是线程安全的。然后input在read的时候,其实读的就是buffer里的内容。
需要注意的是 buffer默认容量大小是1024,好特殊的数字。

原创粉丝点击