博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[十二]JavaIO之BufferedInputStream BufferedOutputStream
阅读量:5749 次
发布时间:2019-06-18

本文共 2072 字,大约阅读时间需要 6 分钟。

功能简介

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

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

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

比如FileInputStream

sGsjBmD28joAAAAASUVORK5CYII=

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的

H+WUgWzjNJx+QAAAABJRU5ErkJggg==

HxHnDO5EnYJIAAAAAElFTkSuQmCC

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

8H7QYhcKwm7M0AAAAASUVORK5CYII=

BufferedOutputStream

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

count 记录有效字节数

AbSdSkiCTrA5AAAAAElFTkSuQmCC

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

如果不设置,默认是8192

ThY+tq7E4GgAAAABJRU5ErkJggg==

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

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

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

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

它的内部借助于flushBuffer方法

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

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

w9LfJmb0pSxOAAAAABJRU5ErkJggg==

write方法

单参数write 一旦缓冲区满了

直接全部调用底层out写入

并且重头开始缓存

D+GBZNavst8gAAAAAElFTkSuQmCC

三参数write

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

如果len大于缓冲区长度

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

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

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

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

+dkSQAAAABJRU5ErkJggg==

总结

既然是缓冲装饰器流

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

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

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

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

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

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

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

z+tlxb1ZXgSYQAAAABJRU5ErkJggg==

转载于:https://www.cnblogs.com/noteless/p/9634065.html

你可能感兴趣的文章
jQuery插件的开发
查看>>
基础,基础,还是基础之JAVA基础
查看>>
Nginx配置文件
查看>>
如何成为一个C++高级程序员
查看>>
iptables 生产环境配置
查看>>
ant android 打包签名和渠道
查看>>
Windows 安装 KMS 与 MAK 的区别
查看>>
java 命令模式 "处理行为" 经典范例
查看>>
实战Nginx(1)-虚拟主机基础配置
查看>>
sparkling-water 安装
查看>>
《马哥出品高薪linux运维教程》wingkeung学习笔记-linux基础入门课程4
查看>>
视图以外点击移除视图
查看>>
Lua中的全局变量与环境
查看>>
linux命令学习(1)-awk
查看>>
ActionBar中SearchView创建的2种方式
查看>>
一个简单的接口,被调用并同步给出响应的方法
查看>>
rhel7.2使用lvm安装虚拟机
查看>>
公司网络很慢很卡的原因分析与处理
查看>>
Hadoop序列化与压缩
查看>>
由“男怕入错行”说开去
查看>>