InputStream之mark & reset

InputStream之mark()_reset()

mark(): Marks the current position in this input stream.在此输入流中标记当前的位置。

reset(): Repositions this stream to the position at the time the <code>mark</code> method was last called on this input stream.将此流重新定位到对此输入流最后调用 mark 方法时的位置。

 

BufferedInputStream的mark和reset方法:

mark方法

 public synchronized void mark(int readlimit) {
        marklimit = readlimit; //marklimit表示标记当前位置,并保证在mark以后最多可以读取readlimit字节数据,mark标记仍有效。如果在mark后读取超过readlimit字节数据,mark标记就会失效,调用reset()方法会有异常
        markpos = pos;   //把当前的位置设置标记位置,当调用reset方法时,会回到这个位置
    }

 

reset方法

 public synchronized void reset() throws IOException {
        getBufIfOpen(); // Cause exception if closed
        if (markpos < 0)
            throw new IOException("Resetting to invalid mark");
        pos = markpos;
    }

 

测试程序:

@Test
public void test4() throws Exception {
    //512默认缓冲流数组buf的大小
    InputStream in = new BufferedInputStream(new FileInputStream("e:\\key\\hello.txt"), 512);

    if (!in.markSupported()) {
        System.out.println("此流不支持mark方法");
        return;
    } else {
        in.mark(12);  //当前的pos为0,在此时标记,当调用reset方法时,会回到流的开始,12表示当最多读取12个字节时,mark标记会失效。但实际情况不是如此。
    }

    int bytesRead = 0;
    byte[] buffer = new byte[12];
    //从文件中按字节读取内容,到文件尾部时read方法将返回-1
    while ((bytesRead = in.read(buffer)) != -1) {
        //将读取的字节转为字符串对象
        String chunk = new String(buffer, 0, bytesRead);
        System.out.print(chunk);
    }
    /**
     * 实际效果不是如此,多情况下在BufferedInputStream类中调用mark(int readlimit)方法后,
     * 即使读取超过readlimit字节的数据,mark标记仍有效,仍然能正确调用reset方法重置。
     * 事实上,mark在JAVA中的实现是和缓冲区相关的。\
     * 只要缓冲区够大,mark后读取的数据没有超出缓冲区的大小,mark标记就不会失效。
     * 如果不够大,mark后又读取了大量的数据,导致缓冲区更新,原来标记的位置自然找不到了。
     */
    //将此流重新定位到对此输入流最后调用 mark 方法时的位置。
    in.reset();
    while ((bytesRead = in.read(buffer)) != -1) {
        //将读取的字节转为字符串对象
        String chunk = new String(buffer, 0, bytesRead);
        System.out.print(chunk);
    }
}

 

附:BufferedInputStream

BufferedInputStream 的作用是为另一个输入流添加一些功能,例如,提供“缓冲功能”以及支持“mark()标记”和“reset()重置方法”。

BufferedInputStream 本质上是通过一个内部缓冲区数组实现的。例如,在新建某输入流对应的BufferedInputStream后,当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据位置。

转载于:https://my.oschina.net/xinxingegeya/blog/265772

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值