包裹在文件读取器周围的缓冲读取器是否从文件读取器获取其文件指针?



我有一个这样的方法:

public void LoadFromFile(){
String record;
try{
FileReader reader = new FileReader("Friends.txt");  
BufferedReader bin = new BufferedReader(reader);
while((record = bin.readLine()) != null){
//do some stuff
}
clientinfo = homeAddress.LoadFromFile(reader);

上面调用的方法homeAddress.LoadFromFile(reader(在另一个类中,如下所示:

public String[] LoadFromFile(FileReader areader){
String record;
try{
BufferedReader bin = new BufferedReader(areader);
while((record = bin.readLine()) != null){
//do some stuff
}
}
bin.close();
bin = null;

我的问题是,我在整个过程中使用相同的FileReader,所以当我将BufferedReader包裹在它周围时,BufferedReader是否使用FileReader的文件指针(从哪里开始读取(?

第一个 BufferedReader 是否更新文件指针,以便第二个 BufferedReader 知道从哪里开始?

这里的关键是"缓冲"一词。不,您不能假设第二个LoadFromFile中的BufferedReader会准确地从调用方中的BufferedReader停止的地方拾取。从文档中:

从字符输入流中读取文本,缓冲字符,以便高效读取字符、数组和行。

(我的强调(

这意味着BufferedReader将在文件中提前读取并将该数据保存在其缓冲区中。因此,第二个BufferedReader将在第一个 字符未读的情况下接听 - 因此,您从第一个BufferedReader消耗的内容和从第二个消耗的内容之间很可能会有差距。

相反:将BufferedReader传递到第二种方法中,并相应地更改其签名。

总的来说,它的签名已经有点偏离了。它不需要知道或关心它是从文件还是其他类型的流中读取;它需要知道的只是它正在从BufferedReader读取(因为它依赖于readLine(。


旁注:在您的代码中,如果在读取时发生异常,您将没有机会清理读取器分配的非 JVM 资源(特别是FileReader(。这就是尝试资源真正有用的地方:

try (
FileReader reader = new FileReader("Friends.txt");  
BufferedReader bin = new BufferedReader(reader);
) {
while((record = bin.readLine()) != null){
//do some stuff
}
clientinfo = homeAddress.LoadFromFile(reader);

在那里,即使readLine发生异常,读取器也会被清理。

从 BufferedReader 的源代码中可以看出,它有一个内部变量nextChar用于读取下一个字符的索引,因此除非您自己存储变量或传递 bufferedreader 实例,否则"指针"将不会继续到下一次调用。

这很简单,可以测试:

朋友.txt:

foo
bar

法典:

import org.junit.Test;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReadingTest {
@Test
public void LoadFromFile() throws IOException {
String record;
try {
FileReader reader = new FileReader("Friends.txt");
BufferedReader bin = new BufferedReader(reader);
while ((record = bin.readLine()) != null) {
System.out.println("1: read " + record);
break;
}
LoadFromFile(reader);
} catch (FileNotFoundException foo) {
System.out.println("file not found from " + new File(".").getAbsolutePath());
}
}
public void LoadFromFile(FileReader areader) {
String record;
try {
BufferedReader bin = new BufferedReader(areader);
while ((record = bin.readLine()) != null) {
System.out.println("2: read " + record);
}
bin.close();
bin = null;
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
}

执行:

1: read foo
Process finished with exit code 0

因此,即使第一次阅读没有完成,第二个读者甚至没有机会阅读。另外,如果在第一次读取后引入 bin.close((,第二次读取将抛出java.io.IOException: Stream closed

正如注释中所建议的,如果您想继续阅读第一种方法中断的第二种方法,最简单的方法是传递相同的缓冲阅读器实例。然后,您必须小心在正确的时间释放资源。

最新更新