java缓冲输入流_java io系列12之 BufferedInputStream(缓冲输入流)的认知、源码和示例...

本章内容包括3个部分:BufferedInputStream介绍,BufferedInputStream源码,以及BufferedInputStream使用示例。

BufferedInputStream 介绍

BufferedInputStream 是缓冲输入流。它继承于

BufferedInputStream 的作用是为另一个输入流添加一些功能,例如,提供“缓冲功能”以及支持“mark()标记”和“reset()重置方法”。

BufferedInputStream 本质上是通过一个内部缓冲区数组实现的。例如,在新建某输入流对应的BufferedInputStream后,当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据位置。

BufferedInputStream 函数列表

BufferedInputStream(InputStream in)

BufferedInputStream(InputStream in,intsize)synchronized intavailable()voidclose()synchronized void mark(intreadlimit)booleanmarkSupported()synchronized intread()synchronized int read(byte[] buffer, int offset, intbyteCount)synchronized voidreset()synchronized long skip(long byteCount)

BufferedInputStream 源码分析(基于jdk1.7.40)

1 packagejava.io;2 importjava.util.concurrent.atomic.AtomicReferenceFieldUpdater;3

4 public class BufferedInputStream extendsFilterInputStream {5

6 //默认的缓冲大小是8192字节7 //BufferedInputStream 会根据“缓冲区大小”来逐次的填充缓冲区;8 //即,BufferedInputStream填充缓冲区,用户读取缓冲区,读完之后,BufferedInputStream会再次填充缓冲区。如此循环,直到读完数据...

9 private static int defaultBufferSize = 8192;10

11 //缓冲数组

12 protected volatile bytebuf[];13

14 //缓存数组的原子更新器。15 //该成员变量与buf数组的volatile关键字共同组成了buf数组的原子更新功能实现,16 //即,在多线程中操作BufferedInputStream对象时,buf和bufUpdater都具有原子性(不同的线程访问到的数据都是相同的)

17 private static final

18 AtomicReferenceFieldUpdater bufUpdater =

19 AtomicReferenceFieldUpdater.newUpdater20 (BufferedInputStream.class, byte[].class, "buf");21

22 //当前缓冲区的有效字节数。23 //注意,这里是指缓冲区的有效字节数,而不是输入流中的有效字节数。

24 protected intcount;25

26 //当前缓冲区的位置索引27 //注意,这里是指缓冲区的位置索引,而不是输入流中的位置索引。

28 protected intpos;29

30 //当前缓冲区的标记位置31 //markpos和reset()配合使用才有意义。操作步骤:32 //(01) 通过mark() 函数,保存pos的值到markpos中。33 //(02) 通过reset() 函数,会将pos的值重置为markpos。接着通过read()读取数据时,就会从mark()保存的位置开始读取。

34 protected int markpos = -1;35

36 //marklimit是标记的最大值。37 //关于marklimit的原理,我们在后面的fill()函数分析中会详细说明。这对理解BufferedInputStream相当重要。

38 protected intmarklimit;39

40 //获取输入流

41 private InputStream getInIfOpen() throwsIOException {42 InputStream input =in;43 if (input == null)44 throw new IOException("Stream closed");45 returninput;46 }47

48 //获取缓冲

49 private byte[] getBufIfOpen() throwsIOException {50 byte[] buffer =buf;51 if (buffer == null)52 throw new IOException("Stream closed");53 returnbuffer;54 }55

56 //构造函数:新建一个缓冲区大小为8192的BufferedInputStream

57 publicBufferedInputStream(InputStream in) {58 this(in, defaultBufferSize);59 }60

61 //构造函数:新建指定缓冲区大小的BufferedInputStream

62 public BufferedInputStream(InputStream in, intsize) {63 super(in);64 if (size <= 0) {65 throw new IllegalArgumentException("Buffer size <= 0");66 }67 buf = new byte[size];68 }69

70 //从“输入流”中读取数据,并填充到缓冲区中。71 //后面会对该函数进行详细说明!

72 private void fill() throwsIOException {73 byte[] buffer =getBufIfOpen();74 if (markpos < 0)75 pos = 0; /*no mark: throw away the buffer*/

76 else if (pos >= buffer.length) /*no room left in buffer*/

77 if (markpos > 0) { /*can throw away early part of the buffer*/

78 int sz = pos -markpos;79 System.arraycopy(buffer, markpos, buffer, 0, sz);80 pos =sz;81 markpos = 0;82 } else if

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值