请选择 进入手机版 | 继续访问电脑版

[IO] JavaIO之 PipedInputStream 和 PipedOutStream(八)

编程语言 编程语言 2744 人阅读 | 0 人回复

管道简介

image.png

对于计算机科学中,管道的含义,很久之前就已经出现,用于表示数据直接交互

它的含义与平时说的管道的含义是类似的,就是直连

JavaIO中的 PipedInputStream 和 PipedOutputStream 就是IO体系中字节流的管道

image.png

java中,PipedOutputStream和PipedInputStream分别是管道输出流和管道输入流

使用管道通信时,必须将PipedOutputStream和PipedInputStream配套使用

大致流程:

我们在线程A中向PipedOutputStream中写入数据,这些数据会自动的发送到与PipedOutputStream对应的PipedInputStream中,进而存储在PipedInputStream的缓冲中;

线程B通过读取PipedInputStream中的数据

image.png

然说是管道,跟现实中的含义有些类似,但是也绝对不能认为他们的数据流方向可以任意

在JavaIO中必须是一个线程通过PipedOutputStream 写入数据;

另外的线程通过与他相连接的PipedInputStream读取数据。

实现原理

PipedOutputStream 中有一个 pipedInputStream

pipedInputStream 内部有一个字节数组 通过initPipe方法进行初始化

调用PipedOutputStream的write方法,实际上调用的是内部pipedInputStream 的 receive方法

而 receive方法,操作的正是pipedInputStream内部的字节数组

所以说,只需要使用connect把管道连接起来

就可以通过PipedOutputStream 写入数据,PipedOutputStream读取数据

数据的中转站,正是pipedInputStream 内的数组

image.png

PipedInputStream

PipedInputStream 内部维护了一个字节数组 buffer 默认大小为1024

通过initPipe方法初始化

image.png

PipedOutputStream 和 PipedInputStream 他们其实操作的都是

PipedInputStream 中的buffer

一个读一个写,所以要记住读和写的位置

注意

此处的in和 out 是相对于 PipedInputStream 的buffer[] 来说的

所以in就是 PipedOutputStream 调用write最终使用的

out就是 PipedInputStream 本身read使用的

image.png

本文作者:程序员潇然 疯狂的字节X https://crazybytex.com/

想要使用管道流必须要有连接的过程

可以在创建 PipedInputStream 的同时一并连接

或者仅仅创建PipedInputStream 稍后连接

而且,内部字节数组的长度是可以设置的,所以也就是又有了默认的或者设置的两种形式

所以总共有四种形式的构造方法

image.png

read

//读取一个字节
public synchronized int read() throws IOException

//读取长度为len的字节到字节数组b 从偏移量off开始写入
public synchronized int read(byte b[], int off, int len)

available

获取可用个数

close

没有系统资源需要关闭,但是还是有些事情要做

connect

connect 调用的是PipedOutputStream中的connect方法

image.png

PipedOutputStream

内部需要PipedInputStream

image.png

构造方法也比较简单

创建一个PipeOutputStream或者创建的同时进行连接

image.png

PipedInputStream中的connect也是借助于PipedOutputStream

他完成了真正的连接

看得出来,不能重复连接,否则会抛出异常

连接后,会对连接进来的PipedInputStream进行必要的初始化 主要就是 in和 out

另外标记已经连接,也正是用这个connected字段来校验是否已经连接的

image.png

write

两个版本的write方法

write(int b) 写入一个字节, 前面24位会被丢弃

write(byte b[], int off, int len) 从指定字节数组的指定位置,读取指定个数的字节, 写入到流

根本还是调用的receive

image.png

flush

flush 将数据输出,此处不同于文件需要调用操作系统进行写入磁盘

需要通知读线程进行读取

image.png

close

image.png

对于管道流的学习,只需要了解其根本即可

那就是PipedOutputStream 内部指向了一个 PipedInputStream

借助于PipedInputStream 内部的循环数组进行数据缓存,进而达到多线程通信的目的

read 和 write方法的含义用法跟InputStream要求的是一样的,没什么特别的

实现细节有兴趣的可以深入研究

common_log.png 转载务必注明出处:程序员潇然,疯狂的字节X,https://crazybytex.com/thread-144-1-1.html

关注下面的标签,发现更多相似文章

文章被以下专栏收录:

    黄小斜学Java

    疯狂的字节X

  • 目前专注于分享Java领域干货,公众号同步更新。原创以及收集整理,把最好的留下。
    包括但不限于JVM、计算机科学、算法、数据库、分布式、Spring全家桶、微服务、高并发、Docker容器、ELK、大数据等相关知识,一起进步,一起成长。
热门推荐
海康摄像头接入 wvp-GB28181-pro平台测试验
[md]### 简介 开箱即用的28181协议视频平台 `https://github.c
[若依]微服务springcloud版新建增添加一个
[md]若依框架是一个比较出名的后台管理系统,有多个不同版本。
[CXX1300] CMake '3.18.1' was not
[md][CXX1300] CMake '3.18.1' was not found in SDK, PATH, or