InputStream 数据流的重复读取

基于业务的需求,我这边需要先读取其中一个字段,然后才能对这个数据流去做相对应得处理,这时就需要进行重复读取

主要有两种方式:一种是通过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

你可能感兴趣的:(Java基础)