根据 Java 官方文档的描述,mark(int readlimit) 方法表示,标记当前位置,并保证在 mark 以后最多可以读取 readlimit 字节数据,mark 标记仍有效。如果在 mark 后读取超过 readlimit 字节数据,mark 标记就会失效,调用 reset() 方法会有异常。
但实际的运行情况却和 Java 文档中的描述并不完全相符。 有时候在 BufferedInputStream 类中调用 mark(int readlimit) 方法后,即使读取超过 readlimit 字节的数据,mark 标记仍有效,仍然能正确调用 reset 方法重置。
事实上,mark 在 Java 中的实现是和缓冲区相关的。只要缓冲区够大,mark 后读取的数据没有超出缓冲区的大小,mark 标记就不会失效。如果不够大,mark 后又读取了大量的数据,导致缓冲区更新,原来标记的位置自然找不到了。
因此,mark 后读取多少字节才失效,并不完全由 readlimit 参数确定,也和 BufferedInputStream 类的缓冲区大小有关。 如果 BufferedInputStream 类的缓冲区大小大于readlimit,在 mark 以后只有读取超过缓冲区大小的数据,mark 标记才会失效。
不懂的看源码,以 BufferedInputStream 为例,看下此流类型的两个成员变量:
private static int DEFAULT_BUFFER_SIZE = 8192;
private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
所以,一般缓冲区足够你用了,通常 mark() 后,reset() 不会抛出异常,但是,在未调用 mark() 前,调用 reset() 会抛异常!原因还是自己查源码^_^!