BufferedReader 的新对象显然仍然关闭

New object of BuferedReader is still apparantly closed

我正在尝试创建一个 class 来读取基于不同事物的文件。但目前的问题是基础阅读部分。

我可以很好地阅读文件中的所有行。然后我可以关闭 reader 并使用新的 BufferedReader 重新分配 reader 变量(我用 reader.ready() 测试了这个,没有抛出 IOException,正如您在下面的代码中看到的那样)。但是,当我从新的 BufferedReader 读取时,它抛出一个 IOException(流关闭):

框架代码如下:

SeparatorReader.java

package SP.Reading;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class SeparatorReader{

    private InputStream stream;
    private BufferedReader reader;

    public SeparatorReader(File f) throws FileNotFoundException{
        stream = new FileInputStream(f);
        reader = new BufferedReader(new InputStreamReader(stream));
    }

    public synchronized String readLine() throws IOException{
        return reader.readLine();
    }

    public synchronized List<String> readAllLines() throws IOException{
        List<String> ls = new ArrayList<String>();
        String line;
        while((line = reader.readLine())!=null){
            ls.add(line);
        }
        return ls;
    }

    public synchronized void reset() throws IOException {
        reader.close();
        reader = new BufferedReader(new InputStreamReader(stream));
        System.out.println(reader.ready());
    }

}

ReadingTester.java

package SP.Reading;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

public class ReadingTester {

    private static boolean error = false;
    private static boolean error811 = false;
    private static boolean error812 = false;

    public static void main(String[] args) {
        File f = buildFile();
        try {
            SeparatorReader fileReader = new SeparatorReader(f);
            System.out.println("Commencing test 1 of 27: Reading all the lines from a file");
            List<String> lines = fileReader.readAllLines();
            fileReader.reset();
            if(lines.get(0).equals("line 1") && lines.get(1).equals("line 2") && lines.get(2).equals("line 3")) System.out.println("Reading all the lines from a file complete!");
            else{
                error = true;
                error811 = true;
                System.out.println("Unable to read all the lines from a file");
            }

            System.out.println("Commencing test 2 of 27: Reading the first line from a file");
            String l = fileReader.readLine();
            fileReader.reset();
            if(l == null) System.out.println("l is null!");
            if(l.equals("line 1")) System.out.println("Reading the first line from a file complete!");
            else{
                error = true;
                error812 = true;
                System.out.println("Unable to read the first line from a file");
            }
        }catch(IOException e){
            e.printStackTrace();
        }

        if(!error) System.out.println("No errors");
        else{
            if(error811) System.out.println("811");
            if(error812) System.out.println("812");
        }
    }

    private static File buildFile(){
        File f = new File("SeparatorReaderFile.txt");
        try {
            f.createNewFile();
            BufferedWriter writer = new BufferedWriter(new FileWriter(f));
            writer.write("line 1");
            writer.newLine();
            writer.write("line 2");
            writer.newLine();
            writer.write("line 3");
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return f;
    }

}

输出也如下:

Commencing test 1 of 27: Reading all the lines from a file
false
Reading all the lines from a file complete!
Commencing test 2 of 27: Reading the first line from a file
java.io.IOException: Stream Closed
        at java.io.FileInputStream.readBytes(Native Method)
        at java.io.FileInputStream.read(Unknown Source)
        at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
        at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
        at sun.nio.cs.StreamDecoder.read(Unknown Source)
        at java.io.InputStreamReader.read(Unknown Source)
        at java.io.BufferedReader.fill(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at SP.Reading.SeparatorReader.readLine(SeparatorReader.java:24)
        at SP.Reading.ReadingTester.main(ReadingTester.java:30)
No errors

在此先感谢您的帮助!

你的问题很简单:

关闭缓冲 reader 将关闭底层输入流。

您在这里也需要一个全新的 InputStream。

调用 "reader.close();" 时,它会同时关闭 reader 和流。

一个简短的解决方案是在 class 中保留文件 f 的副本,并在 reset() 方法中使用 f 重新创建流和 reader。