1

我有这样的方法:

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 知道从哪里开始?

4

2 回答 2

2

这里的关键是“缓冲”这个词。不,您不能假设BufferedReader第二个中的 theLoadFromFile会准确地接听BufferedReader调用者中停止的位置。从文档中

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

(我的重点)

这意味着BufferedReader将在文件中提前读取并将该数据保存在其缓冲区中。因此,第二个BufferedReader字符将与第一个字符未读的第一个字符一起出现——因此,您从第一个字符中消耗的内容与从第二个字符中消耗的内容之间很可能存在差距BufferedReader

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

总的来说,它的签名已经有点偏离了。它不需要知道或关心它是从文件还是其他类型的流中读取;它只需要知道它是从 a 读取的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,也会清理阅读器。

于 2017-08-13T09:07:40.987 回答
0

您可以从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.

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

于 2017-08-13T09:26:12.937 回答