BufferedInputStream的mark和reset失效,无法重复读取流求助
解决BufferedInputStream调用reset后无法重新读取的问题
我来帮你排查下这个问题,我之前做文件读取的时候也踩过类似的坑~
首先,你遇到的核心问题是BufferedInputStream的reset()方法生效有前提条件,如果没满足这些条件,自然没法重置读取位置。下面是最可能的几个错误原因和对应的解决办法:
1. 忘记提前调用mark()方法
BufferedInputStream不会自动帮你标记起始位置,reset()只能回到你之前用mark()标记过的位置。如果在第一次读取前没调用mark(),那reset()根本不知道要回到哪里,自然读不到内容。
这是最常见的错误,看你的代码片段里确实没有调用mark()的步骤,这大概率是问题所在。
2. mark()的readlimit设置过小
调用mark(int readlimit)时,这个参数表示:在标记位置后,最多可以读取多少字节,还能保持标记的有效性。如果第一次读取的字节数超过了这个readlimit,BufferedInputStream就会丢弃之前缓存的标记位置数据,导致reset()失效。
比如你设置的READ_BUFFER_SIZE很大,但readlimit设得比它小,就会出现这个问题。
修正后的代码示例
给你调整后的代码,你可以参考下:
// 假设READ_BUFFER_SIZE是你定义的常量 byte[] buffer = new byte[READ_BUFFER_SIZE]; int bytesRead = 0; File file = new File("slot.txt"); try (InputStream _baseStream = new FileInputStream(file); BufferedInputStream buff = new BufferedInputStream(_baseStream)) { // 关键步骤:在读取前标记文件起始位置,readlimit设为文件大小(确保足够覆盖读取内容) buff.mark((int) file.length()); // 第一次读取 bytesRead = buff.read(buffer, 0, READ_BUFFER_SIZE); System.out.println("第一次读取字节数:" + bytesRead); // 重置到标记的起始位置 buff.reset(); // 第二次读取 bytesRead = buff.read(buffer, 0, READ_BUFFER_SIZE); System.out.println("第二次读取字节数:" + bytesRead); } catch (IOException e) { e.printStackTrace(); }
额外注意点
- 如果你的文件大小超过
Integer.MAX_VALUE(也就是2GB以上),那用(int) file.length()会溢出,这时候可以直接设buff.mark(Integer.MAX_VALUE),不过要注意内存占用问题,毕竟BufferedInputStream会把标记后的内容都缓存起来。 - 如果你之前对
_baseStream做过读取操作(比如创建BufferedInputStream之前就读过FileInputStream),那BufferedInputStream的起始位置是从当前FileInputStream的指针位置开始的,不是文件开头,这时候mark也只会标记这个中间位置,要确保创建BufferedInputStream后马上mark。
内容的提问来源于stack exchange,提问作者user9450093
相关产品推荐
相关产品推荐

