• BufferedInputStream 源码分析


    一、简介

      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位置。

    1     public synchronized void mark(int readlimit) {
    2         marklimit = readlimit;
    3         markpos = pos;
    4     }

       count:

          可以使用的buffer

    二、fill()函数

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

     1 private void fill() throws IOException {
     2         byte[] buffer = getBufIfOpen();
     3         if (markpos < 0)
     4             pos = 0;            /* no mark: throw away the buffer */
     5         else if (pos >= buffer.length)  /* no room left in buffer */
     6             if (markpos > 0) {  /* can throw away early part of the buffer */
     7                 int sz = pos - markpos;
     8                 System.arraycopy(buffer, markpos, buffer, 0, sz);
     9                 pos = sz;
    10                 markpos = 0;
    11             } else if (buffer.length >= marklimit) {
    12                 markpos = -1;   /* buffer got too big, invalidate mark */
    13                 pos = 0;        /* drop buffer contents */
    14             } else {            /* grow buffer */
    15                 int nsz = pos * 2;
    16                 if (nsz > marklimit)
    17                     nsz = marklimit;
    18                 byte nbuf[] = new byte[nsz];
    19                 System.arraycopy(buffer, 0, nbuf, 0, pos);
    20                 if (!bufUpdater.compareAndSet(this, buffer, nbuf)) {
    21                     // Can't replace buf if there was an async close.
    22                     // Note: This would need to be changed if fill()
    23                     // is ever made accessible to multiple threads.
    24                     // But for now, the only way CAS can fail is via close.
    25                     // assert buf == null;
    26                     throw new IOException("Stream closed");
    27                 }
    28                 buffer = nbuf;
    29             }
    30         count = pos;
    31         int n = getInIfOpen().read(buffer, pos, buffer.length - pos);
    32         if (n > 0)
    33             count = n + pos;
    34     }

        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;
                }

  • 相关阅读:
    AC日记——[HNOI2008]GT考试 bzoj 1009
    AC日记——[SCOI2009]游戏 bzoj 1025
    AC日记——[HNOI2010]BOUNCE 弹飞绵羊 洛谷 P3203
    AC日记——旅游 bzoj 2157
    NOIP模拟2017.6.11解题报告
    AC日记——【模板】Link Cut Tree 洛谷 P3690
    AC日记——[SDOI2010]大陆争霸 洛谷 P3690
    [NOI2010]超级钢琴 倍增
    [HNOI2004]L语言 字典树 记忆化搜索
    对拍
  • 原文地址:https://www.cnblogs.com/plxx/p/4794833.html
Copyright © 2020-2023  润新知