基于业务的需求,我这边需要先读取其中一个字段,然后才能对这个数据流去做相对应得处理,这时就需要进行重复读取
主要有两种方式:一种是通过ByteArrayOutputStream,以缓存的方式去处理
第二种是通过mark()和reset()方法,以标记和重置的方式实现
一、ByteArrayOutputStream
利用ByteArrayOutputStream缓存InputStream,以便InputStream的重复使用
具体实现:先读取inputStream中的数据 然后写入 ByteArrayOutputStream中 下次可以重复从ByteArrayOutputStream中读取
缺点:要缓存这个InputStream内存压力可能是比较大的。如果第一次读取只是需要判断该文件流的类型,文件编码等用的话,往往不需要所有的InputStream的数据,或者说只需要前n个字节的话,
这样一来缓存整个InputStream实际上是一种浪费
一、InputStream通过mark和reset方法来实现重复读取
简单来说就是mark(0) 就是“设置字节流的标记,reset()是将“字节流中下一个被读取的位置”重置到“mark()所标记的位置
查看源码:
public synchronized void mark(int readlimit) {}
public synchronized void reset() throws IOException { throw new IOException("mark/reset not supported"); }
public boolean markSupported() { return false; }
其中,第一个方法默认什么都不做,至于reset方法,调用直接抛出异常,第三个方法默认为FALSE,意思就是不支持mark标记,意味着不能重复读取;
对于mark方法中的readLimit参数:意思就是在标记后的有效的字节数;如readLimit设置为10,在进行标记了后,又读取了超过10个字节,再调用reset()重置方法是无效的;
因此,我们需要对这三个方法进行重写,其中InputStream的一些子类已经对其进行了重写,也就意味着该子类支持mark标记的方式进行重复读取;如下面两个子类
1、ByteArrayInputStream
2、BufferedInputStream
参考博客:https://blog.csdn.net/weixin_42865976/article/details/82631152