zoukankan      html  css  js  c++  java
  • PipedInputStream/PipedOutputStream

    PipedInputStream和PipedOutputStream分别是管道输入流和管道输出流.

    它们的作用是让多线程之间可以通过管道进行通讯,在使用管道通信时,必须将PipedInputStream和PipedOutputStream配合使用.

    使用管道通信时,大致流程是:线程A向PipedOutputStream中写入数据,这些数据会自动的发送到对应的pipedInputStream中进行缓存,此时,线程B通过读取PipedInputStream中的数据,就可以实现线程通信了.

    实验一:发送简短的消息

    Sender.java(发送消息)

    public class Sender extends Thread {
        private PipedOutputStream pos = new PipedOutputStream();
    
        public Sender(PipedOutputStream pos) {
        this.pos = pos;
        }
    
        @Override
        public void run() {
             sendShortMessage();
        }
    
        // 发送简单的消息
        public void sendShortMessage() {
        try {
            pos.write("你好啊!".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
            pos.close();
            } catch (IOException e) {
            e.printStackTrace();
            }
        }
        }
    }

    Reciver.java(接受消息)

    public class Reciver extends Thread {
        private PipedInputStream pis = new PipedInputStream();
    
        public Reciver(PipedInputStream pis) {
        this.pis = pis;
        }
    
        @Override
        public void run() {
        byte[] buf = new byte[2048];
        try {
            pis.read(buf);
            pis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Reciver :" + new String(buf));
        }
    }

    PipedTest.java

    public class PipedTest {
        public static void main(String[] args) throws IOException {
        PipedOutputStream pipedOutputStream = new PipedOutputStream();
        PipedInputStream pipedInputStream = new PipedInputStream();
        Sender sender = new Sender(pipedOutputStream);
        Reciver reciver = new Reciver(pipedInputStream);
        pipedInputStream.connect(pipedOutputStream);
        sender.start();
        reciver.start();
        }
    }
    //Reciver :你好啊!

    实验一很好理解:

    pipedInputStream.connect(pipedOutputStream);方法把PipedOutPutStream和PipedInputStream关联了起来.
    Sender通过write()方法,向PipedInputStream中写入"你好啊!",查看PipedOutputStream的writer()方法可知,其实是调用了PipedinputStream的receive()方法,继续查看该方法可知,PipedinputStream的
    receive()方法,其实就是把数据保存到自己的byte buffer[]数组中,而且其数组的默认大小为1024.
    Reciver通过read()方法,从自己的byte buffer[]数组中读取数据.

    实验二:发送较长的消息

     Sender.java(发送消息)

    public class Sender extends Thread {
        private PipedOutputStream pos = new PipedOutputStream();
    
        public Sender(PipedOutputStream pos) {
        this.pos = pos;
        }
    
        @Override
        public void run() {
        sendShortMessage();
        }
    
        // 发送较长的消息
        public void sendLongMessage() {
        StringBuilder sb = new StringBuilder();
        // 总共长度是1020个字节
        for (int i = 0; i < 102; i++) {
            sb.append("0123456789");
        }
        // 再写入26个字节。
        sb.append("abcdefghijklmnopqrstuvwxyz");
        // str的总长度是1020+26=1046个字节
        String str = sb.toString();
        try {
            pos.write(str.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
            pos.close();
            } catch (IOException e) {
            e.printStackTrace();
            }
        }
        }
    }

    Reciver.java(接受消息)

    public class Reciver extends Thread {
        private PipedInputStream pis = new PipedInputStream();
    
        public Reciver(PipedInputStream pis) {
        this.pis = pis;
        }
    
        @Override
        public void run() {
        byte[] buf = new byte[2048];
        try {
            pis.read(buf);
            pis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Reciver :" + new String(buf));
        }
    }

     PipedTest.java

    public class PipedTest {
        public static void main(String[] args) throws IOException {
        PipedOutputStream pipedOutputStream = new PipedOutputStream();
        PipedInputStream pipedInputStream = new PipedInputStream();
        Sender sender = new Sender(pipedOutputStream);
        Reciver reciver = new Reciver(pipedInputStream);
        pipedInputStream.connect(pipedOutputStream);
        sender.start();
        reciver.start();
        }
    }

     实验二的运行结果为:Reciver :012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789abcd

    发现收到的数据少了"efghijklmnopqrstuvwxyz",为什么打印出来的数据正好是1024长度.其实上面我们已经说过了,PipedInputStream的byte [] buffer数组的默认长度只有1024,所以上面的输出是这样的.那怎么改才能输出全部内容的?

    我们修改Reciver.java

    public class Reciver extends Thread {
        private PipedInputStream pis = new PipedInputStream();
    
        public Reciver(PipedInputStream pis) {
        this.pis = pis;
        }
    
        @Override
        public void run() {
        reciverLongMessage();
        }
    
        public void reciverLongMessage() {
        while (true) {
            byte[] buf = new byte[1024];
            int len;
            try {
            len = pis.read(buf);
            if (len > 0) {
                System.out.println(new String(buf, 0, len));
            } else {
                break;
            }
            } catch (IOException e) {
            try {
                pis.close();
            } catch (IOException e2) {
                e2.printStackTrace();
            }
            }
        }
        }
    }

     这样就可以正确输出结果啦!

  • 相关阅读:
    牛客IOI周赛17-提高组 卷积 生成函数 多项式求逆 数列通项公式
    6.3 省选模拟赛 Decompose 动态dp 树链剖分 set
    AtCoder Grand Contest 044 A Pay to Win 贪心
    5.29 省选模拟赛 树的染色 dp 最优性优化
    luogu P6097 子集卷积 FST FWT
    CF724C Ray Tracing 扩展欧几里得 平面展开
    5.30 省选模拟赛 方格操作 扫描线 特殊性质
    5.29 省选模拟赛 波波老师 SAM 线段树 单调队列 并查集
    Spring main方法中怎么调用Dao层和Service层的方法
    Bug -- WebService报错(两个类具有相同的 XML 类型名称 "{http://webService.com/}getPriceResponse"。请使用 @XmlType.name 和 @XmlType.namespace 为类分配不同的名称。)
  • 原文地址:https://www.cnblogs.com/zhangj-ymm/p/9860674.html
Copyright © 2011-2022 走看看