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

[IO] JavaIO之BufferedInputStream BufferedOutputStream(十三)

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

功能简介

BufferedInputStream 和 BufferedOutputStream一样,他们都是过滤流

装饰器模式下具体的装饰类

用来装饰InputStream以及OutputStream下的其他的具体的实现类

比如FileInputStream

image.png

BufferedInputStream 和 BufferedOutputStream

都是在内部借助于字节数组,来实现缓存的

BufferedInputStream

BufferedInputStream 内部使用字节数组对输入流进行缓存
protected volatile byte buf[]; 内部的字节数组可能动态增长,动态增长是借助于创建新数组然后复制,重新指向
DEFAULT_BUFFER_SIZE 默认大小8K 8192
private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; 缓冲区最大允许大小
protected int count; 有效字节的个数
protected int pos; buf 数组中读取的下一个字符的下标索引
protected int markpos = -1; 最后一次调用 mark 方法时 pos 字段的值
protected int marklimit; 调用 mark 方法后,在后续调用 reset 方法失败之前所允许的最大提前读取量就是最多支持的个数

buf[]; 用于实际存储字节数组的值

DEFAULT_BUFFER_SIZE 表示默认缓冲区的大小

MAX_BUFFER_SIZE 表示 最大支持的缓冲区大小

这三个字段用于存储缓冲

pos 用于记录读取位置

markpos / marklimit mark功能使用

构造方法

说了很多遍的装饰器模式,是你还有你

他的使用,必然离不开 InputStream

而且,它内部还会维护一个 InputStream

看下构造方法,如果不指定大小,那么将会使用默认大小

如果指定了大小,只要合法,将会创建字节数组

而且会调用父类的构造方法

父类FilterInputStream中 in是protected的

image.png

image.png

read

提供了两个版本的read

public int read();
public int read(byte[] b,int off, int len);

多参数的read方法将会持续读取尽可能多的数据,直到:

已经读取了指定的字节数,

底层流的 read 方法返回 -1,指示文件末尾(end-of-file),或者

底层流的 available 方法返回 0,指示将阻塞后续的输入请求

skip /available/mark/reset/markSupported 同InputStream的协议语义

跳过指定个数

获取可用个数

做标记

回到标记点

测试是否支持mark 和reset方法

close

虽然并不是直接打开资源,但是它涉及到内部的InputStream,所以需要cloase

image.png

BufferedOutputStream

BufferedOutputStream内部也是通过字节数组进行缓存的 count 记录有效字节数

image.png

构造方法也可以设置,初始化大小

如果不设置,默认是8192

image.png

BufferedOutputStream 内部通过字节数组进行缓存

也就是数据不直接写入磁盘

而是先写入到内部缓冲区中

所以说,flush 方法是必须的,用来执行实际写入的操作

它的内部借助于flushBuffer方法

方法实现很简单,只要有有效字节,就把有效字节通过内部的out对象写入,然后count清0

清零了就可以继续从头写了

image.png

write

单参数write 一旦缓冲区满了 直接全部调用底层out写入

并且重头开始缓存

image.png

三参数write

将数组b 从off偏移量开始,写入len长度到流中

如果len大于缓冲区长度

将所有数据写入,刷新缓冲区

并且直接调用底层out的write 也就是不缓冲了

如果len长度没有超过缓冲区大小 可是 内部缓冲区空间不足够了 刷新缓冲区

最后将参数字节数组的数据,拷贝到缓冲区

image.png

总结

既然是缓冲装饰器流

所以,它内部要维护一个InputStream或者OutputStream

另外,既然提供了缓冲的功能,常用的缓冲功能自然是数组的形式

对于他们两个就是字节数组

他们内部就是都维护了一个字节数组

BufferedInputStream 会将内部底层的流读取的数据,存入到他的缓冲区中,通过BufferedInputStream提供读取功能

BufferedOutputStream 会将写入的数据,存入到他的缓冲区中,在需要的时候,在借助于内部底层的流进行真正写入

缓冲的功能,减少了跟底层磁盘直接交互的io次数,所以说,自然能够提高性能

image.png

common_log.png 转载务必注明出处:程序员潇然,疯狂的字节X,https://crazybytex.com/thread-149-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