无法使用Java BufferedReader从文件中读取:Stream已关闭

时间:2017-11-11 20:50:10

标签: java

我必须在Java中为“玩具语言”创建一个迷你解释器,在这个项目中,我必须包含一个FileTable,它是一个具有私有字段HashMap<Integer, FileData>的类,其中FileData是:< / p>

public class FileData {
    private String fileName;
    private BufferedReader fileDescriptor;

    // methods...
}

另外,我有另一个类OpenRFile,它有一个方法execute(String fileName)。此方法为给定的fileName创建BufferedReader对象,并在FileTable中添加FileData对象。

public class OpenRFile implements Statement {
    private String varName;
    private String fileName;

    // methods...
    public OpenRFile(String v, String f) {
        this.varName = v;
        this.fileName = f;
    }

    @Override
    public PrgState execute(PrgState p) {
        IDictionary<Integer, FileData> fileTable = p.getFileTable();
        IDictionary<String, Integer> symTable = p.getSymTable();

        if (symTable.contains(this.varName))
            throw new InterpreterException("Var name already exists.");

        for (Integer i: fileTable.getAll()) {
            if (fileTable.get(i).getFileName().equals(this.fileName))
                throw new InterpreterException("File is already open.");
        }

        try (BufferedReader br = new BufferedReader(new FileReader(this.fileName))) {
            Integer id = IDGenerator.generateID();
            symTable.add(this.varName, id);
            fileTable.add(id, new FileData(this.fileName, br));
        }
        catch (IOException e) {
            throw new InterpreterException(e.getMessage());
        }

        return p;
    }

    @Override
    public String toString() {
        return "OpenRFile(" + this.varName + ", " + this.fileName + ");";
    }
}

稍后,在另一个类ReadFile中,方法execute只从FileData检索FileTable对象,并在readLine()上调用方法BufferedReader {1}}对象,这是我收到Steam closed错误的时刻。

public class ReadFile implements Statement {
    private Expression exp;
    private String varName;

    // methods...
    public ReadFile(Expression e, String v) {
        this.exp = e;
        this.varName = v;
    }

    @Override
    public PrgState execute(PrgState p) {
        IDictionary<String, Integer> symTable = p.getSymTable();
        IDictionary<Integer, FileData> fileTable = p.getFileTable();

        Integer id = this.exp.eval(symTable);

        if (!fileTable.contains(id))
            throw new InterpreterException("File not found.");

        Integer read;

        try  {
            BufferedReader br = fileTable.get(id).getFileDescriptor();
            //BufferedReader br = new BufferedReader(new FileReader(fileTable.get(id).getFileName()));
            String line = br.readLine();
            if (line == null)
                read = 0;
            else
                read = Integer.parseInt(line);
        }
        catch (IOException e) {
            throw new InterpreterException(e.getMessage());
        }

        if (symTable.contains(this.varName))
            symTable.update(this.varName, read);
        else
            symTable.add(this.varName, read);

        return p;
    }

    @Override
    public String toString() {
        return "ReadFile(" + this.exp + ")";
    }
}

如果我从FileData对象中检索fileName并创建一个新的BufferedReader对象,它就可以工作。但是如果我尝试直接在我已经拥有的对象上调用readLine(),我就会收到错误。

1 个答案:

答案 0 :(得分:2)

您已在try-with-resources块中创建了BufferedReader和FileReader。这意味着,在try块之后直接调用了close()方法,就像有finally{fileReader.close();bufferedReader.close()}一样。