关键是参数readAheadLimit的解释,从字面上看是往前读的限制 ,也就是表示“可以再读多少”。再看详细解释:

是指当还保留有此mark时(i.e.mark未变化),可以再读入字符数的限制。当所读字符数达到此限制(即等于该限制)或超过此限制之后尝试重设该流的话(reset the stream),就会导致失败,比方说上例中的异常(产生的原因就是读入的字符数等于readAheadLimit,都是4)。当限制值大于输入缓存(所谓输入缓存,BufferedReader类有两个构造子,其一就有这个参数,无参版本就以默认值替代,大小是8192)时,就会分配一个大小不小于限制值的新缓存(这里说不小于其实就是等于),因此要小心使用大数值。虽然已晓得,但我们再用源码来验证一下上述说法,关键代码在BufferedReader

fill方法中:

Java代码  

/**

* Fills the input buffer, taking the mark into account if it is valid.

*/

private void fill() throws IOException {

int dst;

if (markedChar <= UNMARKED) {

/* No mark */

dst = 0;

} else {

/* Marked */

int delta = nextChar - markedChar;

if (delta >= readAheadLimit) {

/* Gone past read-ahead limit: Invalidate mark */

markedChar = INVALIDATED;

readAheadLimit = 0;

dst = 0;

} else {

if (readAheadLimit <= cb.length) {

/* Shuffle in the current buffer */

System.arraycopy(cb, markedChar, cb, 0, delta);

markedChar = 0;

dst = delta;

} else {

/* Reallocate buffer to accommodate read-ahead limit */

char ncb[] = new char[readAheadLimit];

System.arraycopy(cb, markedChar, ncb, 0, delta);

cb = ncb;

markedChar = 0;

dst = delta;

}

nextChar = nChars = delta;

}

}

int n;

do {

n = in.read(cb, dst, cb.length - dst);

} while (n == 0);

if (n > 0) {

nChars = dst + n;

nextChar = dst;

}

}

可以看到 nextChar - markedChar >= readAheadLimit 就会被视为Gone past read-ahead limit: Invalidate mark

这里的nextChar是int型,指示当前读入指针下一字符的位置,比如未读前就是0,读了一个字符之后就是1,还有看当非readAheadLimit <= cb.length时,也即readAheadLimit > cb.length,就分配新缓存了,缓存大小就是readAheadLimit,而nextChar在此fill操作中是不变的,所以仍是dst,即delta。最后的读n值主要是为了给nChars赋值,nChars含义应该是总共流中有多少字符,这样也就有了read方法中的判断:

Java代码  

if (nextChar >= nChars)

return -1;

2010.04.27 更正:

原帖中有bug:不是所读超过readAheadLimit就会报异常,而是还有个更大的前提条件,就是所读字符已越过流尾时。

综述:当所读字符已越过流尾时,才可能再判断所读字符数是否大于等于readAheadLimit。

Java代码  

import java.io.BufferedReader;

import java.io.IOException;

import java.io.StringReader;

public class Test {

public static void main(String[] args) throws IOException {

String s = "This is the internal StringReader buffer.";

StringReader stringReader = new StringReader(s);

BufferedReader bufReader = new BufferedReader(stringReader);

// Read from the underlying StringReader.

char[] arr = new char[s.length()];

bufReader.read(arr, 0, arr.length - 14);

System.out.println(arr);

// Call mark after having read all but the last 10

// characters from the StringReader.

if(bufReader.markSupported()) {

System.out.println("mark supported.");

bufReader.mark(3);// change to 15, Mark invalid occurs

}

bufReader.read(arr, arr.length - 14, 14);

bufReader.read();

System.out.println(arr);

bufReader.reset();

stringReader.close();

bufReader.close();

}

}

java bufferedreader mark_BufferedReader之mark与reset初探相关推荐

  1. Java BufferedReader reset()方法及示例

    BufferedReader类的reset()方法 (BufferedReader Class reset() method) reset() method is available in java. ...

  2. Java BufferedReader类简介说明

    转自: Java BufferedReader类简介说明 下文讲述BufferedReader类的功能简介说明,如下所示: BufferedReader类中提供以下功能:缓冲字符输入流Buffered ...

  3. java:BufferedReader接受输入进来的2个数字,并将它们相加

    java:BufferedReader接受输入进来的2个数字,并将它们相加 //接受输入进来的2个数字,并将它们相加BufferedReader buf = null;buf = new Buffer ...

  4. InputStream中通过mark和reset方法重复利用缓存

    通过缓存InputStream可重复利用一个InputStream,但是要缓存一整个InputStream内存压力可能是比较大的.如果第一次读取InputStream是用来判断文件流类型,文件编码等用 ...

  5. Java BufferedReader

    Java BufferedReader class is a part of java.io package. Java BufferedReader类是java.io包的一部分. BufferedR ...

  6. Java BufferedReader mark()方法与示例

    BufferedReader类mark()方法 (BufferedReader Class mark() method) mark() method is available in java.io p ...

  7. java IO接口中的mark和reset方法

    public void mark(int readlimit) 方法的功能是对输入流进行定位,如果是字节流,则定位字节,如果是字符流则定位字符.参数readlimit指的是在mark之后,可以从输入流 ...

  8. Java BufferedReader skip()方法与示例

    BufferedReader类skip()方法 (BufferedReader Class skip() method) skip() method is available in java.io p ...

  9. java BufferedReader

    import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import ja ...

最新文章

  1. HTML和CSS初级前端面试题汇总(持续补充)
  2. 服务器3个w目录文件夹,第 4 章 目录服务器条目 (Sun Java System Directory Server Enterprise Edition 6.2 管理指南)...
  3. 定时器取数据时实时进来的数据_Redis-数据淘汰策略amp;持久化方式(RDB/AOF)amp;Redis与Memcached区别...
  4. python中画圆的代码_Python使用matplotlib绘制圆形代码实例
  5. 优秀架构师是怎么炼成的?
  6. 第七次全国人口普查公报(第三号) ——地区人口情况
  7. Mac pip安装allennlp
  8. jq chosen下拉列表被遮挡
  9. linux 安装xz,在Ubuntu 18.04 LTS下安装linux-5.0.8.tar.xz的方法
  10. Sqli-Lab | Less 21-23
  11. git中fatal: Authentication failed for 的问题
  12. oracle中的rownumber,oracle中row_number和rownum的区别和联系(翻译)
  13. ip用int类型存储
  14. 如何批量将多个 PDF 文档快速合并成一个文档
  15. Min-max theorem
  16. RTSP Windows专用播放器EasyPlayer : 稳定、兼容、高效、超低延时
  17. RepRap 3D Printer 入门介绍
  18. AI算法工程师手册,Google软件开发指南,JAX强化学习环境,全国高校生活质量信息汇总,几篇AI前沿论文 | ShowMeAI资讯日报
  19. 关于不定方程解的个数的问题
  20. 第三方中间件-nodemon

热门文章

  1. eclipse配置struts.xml自动提示
  2. chcon命令 selinux 配置等
  3. iOS应用:成功就像中彩票,大半开发者亏本
  4. SVN 版本服务器搭配全过程详解(含服务端、客户端)
  5. 数据结构——马踏棋盘题解(贪心算法)
  6. Swift4 - 动态计算UITableView中tableHeaderView的高度 - 获取子控件高度和宽度
  7. python 的日志logging模块学习
  8. Win7实用技巧之四拯救桌面行动之Jumplist
  9. 主流浏览器的HTTP最大并发连接数
  10. golang goroutine 得到返回值