<p>根据JAVA官方文档的描述mark(int readlimit)方法表示标记当前位置并保证在mark以后最多可以读取readlimit字节<span class=t_tag tagphp?name=%CA%FD%BE%DD>数据</span>mark标记仍有效如果在mark后读取超过readlimit字节数据mark标记就会失效调用reset()方法会有异常
但实际的运行情况却和JAVA文档中的描述并不完全相符 有时候在BufferedInputStream类中调用mark(int readlimit)方法后即使读取超过readlimit字节的数据mark标记仍有效仍然能正确调用reset方法重置 </p><p>事实上mark在JAVA中的实现是和缓沖区相关的只要缓沖区够大mark后读取的数据没有超出缓沖区的大小mark标记就不会失效如果不够大mark后又读取了大量的数据导致缓沖区更新原来标记的位置自然找不到了</p><p>因此mark后读取多少字节才失效并不完全由readlimit参数确定也和BufferedInputStream类的缓沖区大小有关(默认情况下缓沖区大小为) 如果BufferedInputStream类的缓沖区大小大于readlimit在mark以后只有读取超过缓沖区大小的数据mark标记才会失效看下面的例子 </p> view plain
view plain
view plain package packet
import javaioBufferedInputStream
import javaioByteArrayInputStream
import javaioIOException
/**
* @author WuDian
*
*/
public class MarkExample {
public static void main(String[] args) {
try {
// 初始化一个字节数组内有个字节的数据
byte[] bytes={}
// 用一个ByteArrayInputStream来读取这个字节数组
ByteArrayInputStream in=new ByteArrayInputStream(bytes)
// 将ByteArrayInputStream包含在一个BufferedInputStream并初始化缓沖区大小为
BufferedInputStream bis=new BufferedInputStream(in)
// 读取字节
Systemoutprint(bisread()+)
// 在字节处做标记同时设置readlimit参数为
// 根据JAVA文档mark以后最多只能读取个字节否则mark标记失效但实际运行结果不是这样
Systemoutprintln(mark)
bismark()
/*
* 连续读取两个字节超过了readlimit的大小mark标记仍有效
*/
// 连续读取两个字节
Systemoutprint(bisread()+)
Systemoutprint(bisread()+)
// 调用reset方法未发生异常说明mark标记仍有效
// 因为虽然readlimit参数为但是这个BufferedInputStream类的缓沖区大小为
// 所以允许读取字节
Systemoutprintln(reset)
bisreset()
/*
* 连续读取个字节超过了缓沖区大小mark标记失效
* 在这个例子中BufferedInputStream类的缓沖区大小大于readlimit
* mark标记由缓沖区大小决定
*/
// reset重置后连续读取个字节超过了BufferedInputStream类的缓沖区大小
Systemoutprint(bisread()+)
Systemoutprint(bisread()+)
Systemoutprint(bisread()+)
// 再次调用reset重置抛出异常说明mark后读取个字节mark标记失效
Systemoutprintln(reset again)
bisreset()
} catch (IOException e) {
// TODO Autogenerated catch block
eprintStackTrace()
}
}
}
运行结果如下
mark reset reset again javaioIOException Resetting to invalid mark at javaioBufferedInputStreamreset(BufferedInputStreamjava)
at packetMarkExamplemain(MarkExamplejava) 同样的在调用mark(int readlimit)方法时如果readlimit大于BufferedInputStream类缓沖区的大小缓沖区会被扩大那mark后最多就可以读readlimit字节
简言之BufferedInputStream类调用mark(int readlimit)方法后读取多少字节标记才失效是取readlimit和BufferedInputStream类的缓沖区大小两者中的最大值而并非完全由readlimit确定这个在JAVA文档中是没有提到的
JAVA中mark()和reset()用法的通俗理解
mark就像书签一样在这个BufferedReader对应的buffer里作个标记以后再调用reset时就可以再回到这个mark过的地方mark方法有个参数通过这个整型参数你告诉系统希望在读出这么多个字符之前这个mark保持有效读过这么多字符之后系统可以使mark不再有效而你不能觉得奇怪或怪罪它这跟buffer有关如果你需要很长的距离那么系统就必须分配很大的buffer来保持你的mark //eg //reader is a BufferedReader
readermark()//要求在个字符之内这个mark应该保持有效系统会保证buffer至少可以存储个字符int a = readerread()//读了一个字符int b = readerread()//又读了一个字符
//做了某些处理发现需要再读一次readerreset()readerread()//读到的字符和a相同readerread()//读到的字符和b相同