JAVA BufferedReader 的 mark()、reset() 方法

介绍

mark() 通常与 reset() 搭配使用

mark() 方法

标记当前位置

声明:

mark(int readlimit)

reset() 方法

将流重新定位到最近标记的位置

声明:

reset()

例子

文件

准备 1.txt 文件,内容如下:

李雷
韩梅梅
lucy
lili

package std1;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class Buffered的MarkReset方法 {

    public static void main(String[] args) throws Exception {
        FileInputStream fis = new FileInputStream("1.txt");
        InputStreamReader isr = new InputStreamReader(fis);
        BufferedReader br = new BufferedReader(isr);

        // 读取第一行
        String line = br.readLine();
        System.out.println(line);

        // 读取第一行后,进行 mark() 标记,标记在第二行开始位置
韩梅梅
        br.mark(0);

        // 读取第二行
        line = br.readLine();
        System.out.println(line);

        // 读取第三行
        line = br.readLine();
        System.out.println(line);

        // 重置后,定位到上一次标记的位置,即:第二行开始位置
        br.reset();

        // 又从第二行开始位置读取
        line = br.readLine();
        System.out.println(line);

        br.close();
        isr.close();
        fis.close();
    }
}

执行结果

李雷 // 读取第一行后,进行 mark() 标记,标记在第一行结束位置
韩梅梅
lucy // 读取第三行后,进行 reset() 重置,定位到第一行结束位置
韩梅梅 // 再次读取时,从第二行开始读取

mark() 参数

保证在 mark 以后最多可以读取 readlimit 字节数据,mark 标记仍有效。

如果在 mark 后读取 超过 readlimit 字节数据,mark 标记就会失效,调用 reset() 方法会有异常。

实际情况

从上面例子可知,调用 mark(int readlimit) 方法,readlimit 参数未 0,读取超过 readlimit 字节的数据,mark 标记仍有效,仍然能正确调用 reset() 方法重置。

注意:从上面例子,可能读取到某个位置就会报错,也可能不报错

原因

mark() 方法和缓冲区相关。只要缓冲区够大mark 后读取的数据没有超出缓冲区的大小,mark 标记就不会失效。如果不够大,mark 后又读取了大量的数据,导致缓冲区更新,原来标记的位置自然找不到了。

因此,mark 后读取多少字节才失效,并不完全由 readlimit 参数确定,也和 缓冲区大小有关

例子-报错

package std1;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class Buffered的MarkReset报错 {

    public static void main(String[] args) throws Exception {
        FileInputStream fis = new FileInputStream("1.txt");
        InputStreamReader isr = new InputStreamReader(fis);
        // 缓冲区设置为8个字符
        BufferedReader br = new BufferedReader(isr,8);

        // 读取第一行
        String line = br.readLine();
        System.out.println(line);

        // 读取第一行后,进行标记
        br.mark(0);

        // 读取第二行
        line = br.readLine();
        System.out.println(line);

        // 读取第三行
        line = br.readLine();
        System.out.println(line);

        // 重置
        br.reset();

        // 重置后,定位到上一次标记的位置,开始继续读取
        // 所以又读取到第二行
        line = br.readLine();
        System.out.println(line);

        br.close();
        isr.close();
        fis.close();
    }
}

如何设置才保证不报错

是否报错,与 缓冲区大小,文件大小、readlimit 的大小有关,为了确保不报错,可以简单设置 readlimit 值为 文件大小+1

例子-一定不报错

package std1;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class Buffered的MarkReset一定不报错 {

    public static void main(String[] args) throws Exception {
        File file = new File("1.txt");
        FileInputStream fis = new FileInputStream(file);
        InputStreamReader isr = new InputStreamReader(fis);
        // 缓冲区设置为8个字符
        BufferedReader br = new BufferedReader(isr,8);

        // 读取第一行
        String line = br.readLine();
        System.out.println(line);

        // 读取第一行后,进行标记
        // 参数是文件大小+1
        br.mark((int)file.length()+1);

        // 读取第二行
        line = br.readLine();
        System.out.println(line);

        // 读取第三行
        line = br.readLine();
        System.out.println(line);

        // 重置
        br.reset();

        // 重置后,定位到上一次标记的位置,开始继续读取
        // 所以又读取到第二行
        line = br.readLine();
        System.out.println(line);

        br.close();
        isr.close();
        fis.close();
    }
}

参考:
https://blog.csdn.net/liuxiao723846/article/details/117693340


原文出处:https://malaoshi.top/show_1IX4sVu08AZa.html