介绍
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