java bufferedreader mark_BufferedReader之mark与reset初探
关键是参数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初探相关推荐
- Java BufferedReader reset()方法及示例
BufferedReader类的reset()方法 (BufferedReader Class reset() method) reset() method is available in java. ...
- Java BufferedReader类简介说明
转自: Java BufferedReader类简介说明 下文讲述BufferedReader类的功能简介说明,如下所示: BufferedReader类中提供以下功能:缓冲字符输入流Buffered ...
- java:BufferedReader接受输入进来的2个数字,并将它们相加
java:BufferedReader接受输入进来的2个数字,并将它们相加 //接受输入进来的2个数字,并将它们相加BufferedReader buf = null;buf = new Buffer ...
- InputStream中通过mark和reset方法重复利用缓存
通过缓存InputStream可重复利用一个InputStream,但是要缓存一整个InputStream内存压力可能是比较大的.如果第一次读取InputStream是用来判断文件流类型,文件编码等用 ...
- Java BufferedReader
Java BufferedReader class is a part of java.io package. Java BufferedReader类是java.io包的一部分. BufferedR ...
- Java BufferedReader mark()方法与示例
BufferedReader类mark()方法 (BufferedReader Class mark() method) mark() method is available in java.io p ...
- java IO接口中的mark和reset方法
public void mark(int readlimit) 方法的功能是对输入流进行定位,如果是字节流,则定位字节,如果是字符流则定位字符.参数readlimit指的是在mark之后,可以从输入流 ...
- Java BufferedReader skip()方法与示例
BufferedReader类skip()方法 (BufferedReader Class skip() method) skip() method is available in java.io p ...
- java BufferedReader
import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import ja ...
最新文章
- HTML和CSS初级前端面试题汇总(持续补充)
- 服务器3个w目录文件夹,第 4 章 目录服务器条目 (Sun Java System Directory Server Enterprise Edition 6.2 管理指南)...
- 定时器取数据时实时进来的数据_Redis-数据淘汰策略amp;持久化方式(RDB/AOF)amp;Redis与Memcached区别...
- python中画圆的代码_Python使用matplotlib绘制圆形代码实例
- 优秀架构师是怎么炼成的?
- 第七次全国人口普查公报(第三号) ——地区人口情况
- Mac pip安装allennlp
- jq chosen下拉列表被遮挡
- linux 安装xz,在Ubuntu 18.04 LTS下安装linux-5.0.8.tar.xz的方法
- Sqli-Lab | Less 21-23
- git中fatal: Authentication failed for 的问题
- oracle中的rownumber,oracle中row_number和rownum的区别和联系(翻译)
- ip用int类型存储
- 如何批量将多个 PDF 文档快速合并成一个文档
- Min-max theorem
- RTSP Windows专用播放器EasyPlayer : 稳定、兼容、高效、超低延时
- RepRap 3D Printer 入门介绍
- AI算法工程师手册,Google软件开发指南,JAX强化学习环境,全国高校生活质量信息汇总,几篇AI前沿论文 | ShowMeAI资讯日报
- 关于不定方程解的个数的问题
- 第三方中间件-nodemon