java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java IO流操作

Java IO流操作(PipeInputStream、SequenceInputStream、BufferedInputStream)

作者:@一头雾水@

管道流主要用于线程间通信,分为管道输入流(PipeInputStream)和管道输出流(PipeOutputStream),本文介绍了如何通过管道流进行数据发送和接收,具有一定的参考价值,感兴趣的可以了解一下

一、PipeInputStream

1、介绍。

管道流的主要作用是可以进行两个线程间的通讯,分为管道输入流(PipeOutputStream)和管道输出流(PipeInputStream)。如果要想进行管道输出,则必须把输出流连在输入流之上

2、代码。

private static final String Pre_Path = "G:\\项目测试\\io流文件测试\\";

public static void main(String[] args) {
    pipedStreamTest();//进行两个线程之间的通信
}

//管道--进行两个线程之间的通信
private static void pipedStreamTest() {
    SendPipedThread sendThread = new SendPipedThread();
    sendThread.start();
    ReceivePipedThread receiveThread = new ReceivePipedThread();
    receiveThread.start();
    try {
        sendThread.outputStream.connect(receiveThread.inputStream);
        Thread.sleep(10000);//10S
        sendThread.stopThread();
        receiveThread.stopThread();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

//管道--每隔500ms,输出当前时间的字节数组
static class SendPipedThread extends Thread {
    PipedOutputStream outputStream = new PipedOutputStream();//输出流

    @Override
    public void run() {
        try {
            while (outputStream != null) {
                String writeStr = "时间:" + DateUtils.nowDateStr("yyyy-MM-dd hh:mm:ss") + "  ";
                System.out.println("Send线程发送:" + writeStr);
                outputStream.write(writeStr.getBytes());
                Thread.sleep(500);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    void stopThread() {
        try {
            if (outputStream != null) {
                outputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

//管道--获取连接管道的字节数组
static class ReceivePipedThread extends Thread {
    PipedInputStream inputStream = new PipedInputStream();//输入流

    @Override
    public void run() {
        try {
            while (inputStream != null) {
                byte[] readBytes = new byte[1024];
                int len;
                while ((len = inputStream.read(readBytes)) != -1) {
                    String readStr = new String(readBytes);
                    System.out.println("Receive线程接收:" + readStr);
                }
                Thread.sleep(10);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    void stopThread() {
        try {
            if (inputStream != null) {
                inputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3、结果。

    Connected to the target VM, address: '127.0.0.1:58908', transport: 'socket'
    Send线程发送:时间:2019-10-24 03:50:40  
    Send线程发送:时间:2019-10-24 03:50:40  
    Receive线程接收:时间:2019-10-24 03:50:40  时间:2019-10-24 03:50:40                                                                                 Send线程发送:时间:2019-10-24 03:50:41  
    Send线程发送:时间:2019-10-24 03:50:41  
    Receive线程接收:时间:2019-10-24 03:50:41  时间:2019-10-24 03:50:41                                                                                 Send线程发送:时间:2019-10-24 03:50:42  
    Send线程发送:时间:2019-10-24 03:50:42  
    Receive线程接收:时间:2019-10-24 03:50:42  时间:2019-10-24 03:50:42                                                                                 Send线程发送:时间:2019-10-24 03:50:43  
    Send线程发送:时间:2019-10-24 03:50:43  
    Receive线程接收:时间:2019-10-24 03:50:43  时间:2019-10-24 03:50:43                                                                                 Send线程发送:时间:2019-10-24 03:50:44  
    Send线程发送:时间:2019-10-24 03:50:44  
    Receive线程接收:时间:2019-10-24 03:50:44  时间:2019-10-24 03:50:44                                                                                 Send线程发送:时间:2019-10-24 03:50:45  
    Send线程发送:时间:2019-10-24 03:50:45  
    Receive线程接收:时间:2019-10-24 03:50:45  时间:2019-10-24 03:50:45                                                                                 Send线程发送:时间:2019-10-24 03:50:46  
    Send线程发送:时间:2019-10-24 03:50:46  
    Receive线程接收:时间:2019-10-24 03:50:46  时间:2019-10-24 03:50:46                                                                                 Send线程发送:时间:2019-10-24 03:50:47  
    Send线程发送:时间:2019-10-24 03:50:47  
    Receive线程接收:时间:2019-10-24 03:50:47  时间:2019-10-24 03:50:47                                                                                 Send线程发送:时间:2019-10-24 03:50:48  
    Send线程发送:时间:2019-10-24 03:50:48  
    Receive线程接收:时间:2019-10-24 03:50:48  时间:2019-10-24 03:50:48                                                                                 Send线程发送:时间:2019-10-24 03:50:49  
    Send线程发送:时间:2019-10-24 03:50:49  
    java.io.IOException: Pipe closed
        at java.io.PipedInputStream.read(PipedInputStream.java:307)
        at java.io.PipedInputStream.read(PipedInputStream.java:377)
        at java.io.InputStream.read(InputStream.java:101)
        at com.zxj.reptile.test.IOStreamTest$ReceivePipedThread.run(IOStreamTest.java:211)
    Send线程发送:时间:2019-10-24 03:50:50  
    java.io.IOException: Pipe closed
        at java.io.PipedInputStream.checkStateForReceive(PipedInputStream.java:260)
        at java.io.PipedInputStream.receive(PipedInputStream.java:226)
        at java.io.PipedOutputStream.write(PipedOutputStream.java:149)
        at java.io.OutputStream.write(OutputStream.java:75)
        at com.zxj.reptile.test.IOStreamTest$SendPipedThread.run(IOStreamTest.java:182)
    Disconnected from the target VM, address: '127.0.0.1:58908', transport: 'socket'
    
    Process finished with exit code 0

二、SequenceInputStream

1、介绍。

SequenceInputStream 可以将两个或多个其他 InputStream 合并为一个。 首先,SequenceInputStream 将读取第一个 InputStream 中的所有字节,然后读取第二个 InputStream 中的所有字节。 这就是它被称为 SequenceInputStream 的原因,因为 InputStream 实例是按顺序读取的。

2、代码。

private static final String Pre_Path = "G:\\项目测试\\io流文件测试\\";

public static void main(String[] args) {
    sequenceStreamTest();//将多个文件复制到同一个文件中
}
//将多个文件复制到同一个文件中
private static void sequenceStreamTest() {
    InputStream inputStream = null;//输入流
    OutputStream outputStream = null;//输出流
    try {
        outputStream = new FileOutputStream(Pre_Path + "sequenceStream\\输出文件.txt");//输出流
        Vector<InputStream> vector = new Vector<>();
        vector.add(new FileInputStream(Pre_Path + "sequenceStream\\a.txt"));
        vector.add(new FileInputStream(Pre_Path + "sequenceStream\\b.txt"));
        vector.add(new FileInputStream(Pre_Path + "sequenceStream\\c.txt"));
        inputStream = new SequenceInputStream(vector.elements());
        //从输入流读取0 到 255数量的字节,并写入输出流中
        int readByte;
        while ((readByte = inputStream.read()) != -1) {
            outputStream.write(readByte);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (inputStream != null) {
                inputStream.close();//SequenceInputStream的close,会将里面的各个流全部关闭
            }
            if (outputStream != null) {
                outputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3、测试用例。

4、结果。

三、BufferedInputStream

1、介绍。

BufferedInputStream继承于FilterInputStream,提供缓冲输入流功能。缓冲输入流相对于普通输入流的优势是,它提供了一个缓冲数组,每次调用read方法的时候,它首先尝试从缓冲区里读取数据,若读取失败(缓冲区无可读数据),则选择从物理数据源(譬如文件)读取新数据(这里会尝试尽可能读取多的字节)放入到缓冲区中,最后再将缓冲区中的内容部分或全部返回给用户.由于从缓冲区里读取数据远比直接从物理数据源(譬如文件)读取速度快。

2、代码。

private static final String Pre_Path = "G:\\项目测试\\io流文件测试\\";

public static void main(String[] args) {
    bufferedStreamTest();//文件的复制(字节缓冲流)
}
//文件的复制(字节缓冲流)
private static void bufferedStreamTest() {
    InputStream inputStream = null;//输入流
    OutputStream outputStream = null;//输出流
    try {
        inputStream = new BufferedInputStream(new FileInputStream(Pre_Path + "bufferStream\\test1.txt"));
        outputStream = new BufferedOutputStream(new FileOutputStream(Pre_Path + "bufferStream\\test2.txt"));
        //从输入流读取0 到 255数量的字节,并写入输出流中
        byte[] readBytes = new byte[1024];
        int len;
        while ((len = inputStream.read(readBytes)) != -1) {
            System.out.println("读取到的字符:\n" + new String(readBytes));
            outputStream.write(readBytes, 0, len);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3、测试用例。

4、结果。

到此这篇关于Java IO流操作(PipeInputStream、SequenceInputStream、BufferedInputStream)的文章就介绍到这了,更多相关Java IO流操作内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:
阅读全文