我有一个这样的方法:
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
。
正如注释中所建议的,如果您想继续阅读第一种方法中断的第二种方法,最简单的方法是传递相同的缓冲阅读器实例。然后,您必须小心在正确的时间释放资源。