一、简介

  BufferedInputStream会缓存一部分数据(默认8K),这个函数的作用就是读取更多的数据到缓存,必要的时候会扩大缓存的内容。

在该类中有几个重要的标志位:markpos,pos,count

  【markpos的作用,marklength区域内的数据表示需要保留的数据,也就是在重置(reset 方法)buffer的时候,这部分数据是不会被删除的,强制要求保留。】  

  pos:

    current position in the buffer, this is the index of the next character to be read from the buffer.

    表示下一个即将读入的字符。

  markpos:

    The value of the pos field at the time the last mark method was called.

    markpos 的数值等于上一次调用mark方法时候的pos位置。

     public synchronized void mark(int readlimit) {
marklimit = readlimit;
markpos = pos;
}

   count:

      可以使用的buffer

二、fill()函数

  当pos>count的时候,调用该方法来扩容。它总会将预留空间的位置挪动到buffer的前端。

 private void fill() throws IOException {
byte[] buffer = getBufIfOpen();
if (markpos < 0)
pos = 0; /* no mark: throw away the buffer */
else if (pos >= buffer.length) /* no room left in buffer */
if (markpos > 0) { /* can throw away early part of the buffer */
int sz = pos - markpos;
System.arraycopy(buffer, markpos, buffer, 0, sz);
pos = sz;
markpos = 0;
} else if (buffer.length >= marklimit) {
markpos = -1; /* buffer got too big, invalidate mark */
pos = 0; /* drop buffer contents */
} else { /* grow buffer */
int nsz = pos * 2;
if (nsz > marklimit)
nsz = marklimit;
byte nbuf[] = new byte[nsz];
System.arraycopy(buffer, 0, nbuf, 0, pos);
if (!bufUpdater.compareAndSet(this, buffer, nbuf)) {
// Can't replace buf if there was an async close.
// Note: This would need to be changed if fill()
// is ever made accessible to multiple threads.
// But for now, the only way CAS can fail is via close.
// assert buf == null;
throw new IOException("Stream closed");
}
buffer = nbuf;
}
count = pos;
int n = getInIfOpen().read(buffer, pos, buffer.length - pos);
if (n > 0)
count = n + pos;
}

    byte[] buffer = getBufIfOpen(); 获取当前buffer的引用

     if (markpos < 0)
              pos = 0;            /* no mark: throw away the buffer */ 整个buffer没有被标记过,也就是没有预留空间。

    else if (pos >= buffer.length)  /* no room left in buffer */   (markpos >0 或=0 )有预留空间,而且没有剩余空间可用。

      if (markpos > 0) {  /* can throw away early part of the buffer */  预留空间的起始位置不在buffer的开始位置
                  int sz = pos - markpos;    挪动预留空间
                  System.arraycopy(buffer, markpos, buffer, 0, sz);
                  pos = sz;
                  markpos = 0;

      } else if (buffer.length >= marklimit) { 如果marklimit的值小于缓存的长度,说明buffer很大,从内存使用的角度考虑,此时不宜再增大缓存的容量,

                         在这种情形下直接丢弃buf中的已有内容;
                  markpos = -1;   /* buffer got too big, invalidate mark */
                  pos = 0;        /* drop buffer contents */

     } else {            /* grow buffer */ 2倍扩展buffer
                  int nsz = pos * 2;
                  if (nsz > marklimit)
                      nsz = marklimit;
                  byte nbuf[] = new byte[nsz];
                  System.arraycopy(buffer, 0, nbuf, 0, pos);
                  if (!bufUpdater.compareAndSet(this, buffer, nbuf)) { 确保多线程情况下的可见性。
                      // Can't replace buf if there was an async close.
                      // Note: This would need to be changed if fill()
                      // is ever made accessible to multiple threads.
                      // But for now, the only way CAS can fail is via close.
                      // assert buf == null;
                      throw new IOException("Stream closed");
                  }
                  buffer = nbuf;
            }

BufferedInputStream 源码分析的更多相关文章

  1. java.io.BufferedInputStream 源码分析

    BufferedInputStream是一个带缓冲区的输入流,在读取字节数据时可以从底层流中一次性读取多个字节到缓冲区,而不必每次读取操作都调用底层流,从而提高系统性能. 先介绍几个关键属性 //默认 ...

  2. 【Zookeeper】源码分析之持久化--FileSnap

    一.前言 前篇博文已经分析了FileTxnLog的源码,现在接着分析持久化中的FileSnap,其主要提供了快照相应的接口. 二.SnapShot源码分析 SnapShot是FileTxnLog的父类 ...

  3. 【Zookeeper】源码分析之持久化(二)之FileSnap

    一.前言 前篇博文已经分析了FileTxnLog的源码,现在接着分析持久化中的FileSnap,其主要提供了快照相应的接口. 二.SnapShot源码分析 SnapShot是FileTxnLog的父类 ...

  4. hadoop的RPC机制 -源码分析

    这些天一直奔波于长沙和武汉之间,忙着腾讯的笔试.面试,以至于对hadoop RPC(Remote Procedure Call Protocol ,远程过程调用协议,它是一种通过网络从远程计算机程序上 ...

  5. Spark大师之路:广播变量(Broadcast)源码分析

    概述 最近工作上忙死了……广播变量这一块其实早就看过了,一直没有贴出来. 本文基于Spark 1.0源码分析,主要探讨广播变量的初始化.创建.读取以及清除. 类关系 BroadcastManager类 ...

  6. TOMCAT8源码分析——SESSION管理分析(上)

    前言 对于广大java开发者而已,对于J2EE规范中的Session应该并不陌生,我们可以使用Session管理用户的会话信息,最常见的就是拿Session用来存放用户登录.身份.权限及状态等信息.对 ...

  7. Tomcat源码分析——Session管理分析(上)

    前言 对于广大java开发者而已,对于J2EE规范中的Session应该并不陌生,我们可以使用Session管理用户的会话信息,最常见的就是拿Session用来存放用户登录.身份.权限及状态等信息.对 ...

  8. Hadoop的RPC机制源码分析

    分析对象: hadoop版本:hadoop 0.20.203.0 必备技术点: 1. 动态代理(参考 :http://www.cnblogs.com/sh425/p/6893662.html )2. ...

  9. HDFS源码分析DataXceiver之整体流程

    在<HDFS源码分析之DataXceiverServer>一文中,我们了解到在DataNode中,有一个后台工作的线程DataXceiverServer.它被用于接收来自客户端或其他数据节 ...

随机推荐

  1. JS笔记 入门第一

    WHY? 一.你知道,为什么JavaScript非常值得我们学习吗? 1. 所有主流浏览器都支持JavaScript. 2. 目前,全世界大部分网页都使用JavaScript. 3. 它可以让网页呈现 ...

  2. KVO 的使用和举例

    KVO(key-value Observer),通过命名可以联想到,一个监视着监视着键值配对,让一个对象A来监视另一个对象B中的键值,一旦B中的受监视键所对应的值发生了变化,对象A会进入一个回调函数, ...

  3. 灵动标签内sql语句调用

    本节来介绍帝国cms中,灵动标签中如何写数据库调用我们所要的信息.方便一些没有学习过数据库的朋友 转载请注明出处:谢寒的博客 灵动标签默认的语法 [e:loop={栏目ID/专题ID,显示条数,操作类 ...

  4. 百度云世界里的“七种武器”:PCS、BAE、Site App、ScreenX等

    如果说去年百度世界的关键词是“百度新首页”的话,那么今年在研发者人群中,对百度世界最深的印象就是“七种武器”,即在云的世界里,百度为开发者所提供的包括个人云存储.LBS.移动云测试中心等在内的七种工具 ...

  5. HDU 1507 Uncle Tom's Inherited Land*

    题目大意:给你一个矩形,然后输入矩形里面池塘的坐标(不能放东西的地方),问可以放的地方中,最多可以放多少块1*2的长方形方块,并输出那些方块的位置. 题解:我们将所有未被覆盖的分为两种,即分为黑白格( ...

  6. poj 2503 Babelfish(Map、Hash、字典树)

    题目链接:http://poj.org/bbs?problem_id=2503 思路分析: 题目数据数据量为10^5, 为查找问题,使用Hash或Map等查找树可以解决,也可以使用字典树查找. 代码( ...

  7. 今天刚申请成为Uber司机 已经接了5单了....大家有什么想问的吗?

    今天刚申请成为Uber司机  已经接了5单了....大家有什么想问的吗? 滴滴快车单单2.5倍,注册地址:http://www.udache.com/如何注册Uber司机(全国版最新最详细注册流程)/ ...

  8. nodejs--express开发博客系统(三)

    上一节已经实现了登录.注册.发表文章和文章读取的功能,今天咱加上评论.文章页面和作者页面. 评论只能在进入文章页面后才能进行,所以咱们先写文章页面. 在上一节的代码中,我已经给文章标题添加了超链接了, ...

  9. wpf全局异常

    在App.xaml文件中 添加DispatcherUnhandledExceptionEventArgs 新增对应事件

  10. 将从数据库中获取的数据 ,以HTML表格的形式显示

    1.HTML页面 <body> <form id="form1" runat="server"> <div id="di ...