我有一个像这样的方法:
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知道从哪里开始?
答案 0 :(得分:2)
这里的关键是“缓冲”这个词。不,您不能认为第二个BufferedReader
中的LoadFromFile
会准确到达来电者BufferedReader
所在的位置。来自the documentation:
从字符输入流中读取文本,缓冲字符,以便提供字符,数组和行的有效读取。
(我的重点)
这意味着BufferedReader
将在文件中预读并将该数据保存在其缓冲区中。因此,第二个BufferedReader
将会拾取第一个未读取的第一个字符 - 所以您可能在第一个BufferedReader
消耗的内容与第二个消费内容之间存在差距。
相反:将BufferedReader
传递给第二种方法,相应地更改其签名。
一般来说,它的签名已经有点过了。它不应该知道或关心它是从文件还是其他类型的流中读取;它需要知道的是它是从BufferedReader
读取的(因为它依赖于readLine
)。
附注:在您的代码中,如果在读取时发生异常,您将无法清理读者分配的非JVM资源(特别是FileReader
)。这是try-with-resources非常有用的地方:
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
中发生异常,也会清理读者。
答案 1 :(得分:0)
你可以从source code of BufferedReader看到它有一个内部变量nextChar
用于读取下一个字符的索引,所以除非你自己存储变量或者传递bufferedreader实例, “指针”不会继续进行下一次通话。
这很简单,可以测试:
Friends.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
。
正如评论中所建议的那样,如果你想继续阅读第一种方法,那么最简单的方法是传递相同的bufferedreader实例。你必须小心在适当的时候释放资源。