Java IO<5>管道流PipedOutputStream PipedInputStream

在java中,PipedOutputStream和PipedInputStream分别是管道输出流和管道输入流。它们的作用是让多线程可以通过管道进行线程间的通讯。在使用管道通信时,必须将PipedOutputStream和PipedInputStream配套使用。

使用管道通信时,大致的流程是:我们在线程A中向PipedOutputStream中写入数据,这些数据会自动的发送到与PipedOutputStream对应的PipedInputStream中,进而存储在PipedInputStream的缓冲中;此时,线程B通过读取PipedInputStream中的数据。就可以实现,线程A和线程B的通信。

可以使用两个管道共有的connect()方法使之相关联。PipedInputStream和PipedOutputStream都拥有一个可以互相关联的connect()方法。

管道输入流PipedInputStream与管道输出流PipedOutputStream建立连接

一般我们使用都是先定义一个管道输入流PipedInputStream对象和管道输出流PipedOutputStream对象,然后将他们关联起来,建立了一条”管道”。

使用connect()方法建立连接:

PipedInputStream pipedInputStream=new PipedInputStream();
PipedOutputStream pipedOutputStream=new PipedOutputStream();
try {
    pipedInputStream.connect(pipedOutputStream);
} catch (IOException e) {
    e.printStackTrace();
}

不使用connect()方法:

PipedInputStream pipedInputStream=new PipedInputStream();
PipedOutputStream pipedOutputStream=null;
try {
     pipedOutputStream = new PipedOutputStream(pipedInputStream);
} catch (IOException e) {
     e.printStackTrace();
}

使用示例:

import java.util.Random;

public class Test {
    //管道输出流
    private static PipedOutputStream outputStream = new PipedOutputStream();
    //管道输入流
    private static PipedInputStream inputStream = new PipedInputStream();

    private static byte[] buf = new byte[1024];
    // int nextInt(int n)
    //该方法的作用是生成一个随机的int值,该值介于[0,n)的区间,也就是0到n之间的随机int值,包含0而不包含n。
    private static Random random = new Random();

    public static void main(String[] args) throws Exception {
        DataInputStream dataInputStream = new DataInputStream(inputStream);
        DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
        String str = "asdfghjklqwertyuiopzxcvbnm";
        //输出线程
        Runnable producer = () -> {
            try {
                while (true) {
                    Thread.sleep(1000);
                    int len = random.nextInt(20) + 1;
                    dataOutputStream.writeInt(len);
                    String randomString = getRandomString(len);
                    System.out.println("发送" + randomString);
                    dataOutputStream.write(randomString.getBytes());
                    dataOutputStream.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        };
        //输入线程
        Runnable consumer = () -> {
            try {
                while (true) {
                    int len = dataInputStream.readInt();
                    dataInputStream.readFully(buf, 0, len);
                    System.out.println("收到" + new String(buf, 0, len));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        };
        //连接管道
        inputStream.connect(outputStream);
        //启动线程
        new Thread(producer).start();
        new Thread(consumer).start();
    }

    //生成随机字符串
    public static String getRandomString(int length) {
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }
}

注:本例忽略了流的关闭。请在处理流的过程中,务必保证关闭流,或者使用jdk7引入的try-resources代替显示地调用close方法的方式。

import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipeStream {
    //管道输出流
    private static PipedOutputStream outputStream = new PipedOutputStream();
    //管道输入流
    private static PipedInputStream inputStream = new PipedInputStream();

    public static void main(String[] args) throws Exception {
        //输出线程
        Runnable out = ()-> {
            try {
                while(true) {
                    Thread.sleep(1000);
                    outputStream.write("pipe".getBytes());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        };
        //输入线程
        Runnable in = ()-> {
            try {
                byte[] bytes = new byte [1024];
                int len;
                while ((len = inputStream.read(bytes)) != -1) {
                    System.out.println(new String(bytes,0,len));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        };
        //连接管道
        inputStream.connect(outputStream);
        //启动线程
        new Thread(out).start();
        new Thread(in).start();
    }
}
posted @ 2022-04-08 14:15  aixueforever  阅读(99)  评论(0编辑  收藏  举报