Reputation: 155
I have to create a mini-interpreter in Java for a "Toy Language" and in this project, I have to include a FileTable which is a class having as private field a HashMap<Integer, FileData>
, where FileData is:
public class FileData {
private String fileName;
private BufferedReader fileDescriptor;
// methods...
}
Also, I have another class OpenRFile which has a method execute(String fileName)
. This method creates a BufferedReader
object for the given fileName and a FileData
object which is added in the FileTable.
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 + ");";
}
}
Later, in another class: ReadFile
, the method execute
just retrieves the FileData
object from the FileTable
and calls the method readLine()
on the BufferedReader
object, and this is the moment when I get the Steam closed
error.
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 + ")";
}
}
If I retrieve the fileName from the FileData
object and create a new BufferedReader
object, it works. But if I try to call readLine()
directly on the object I already have, I get the error.
Upvotes: 2
Views: 306
Reputation: 4919
You have created BufferedReader and FileReader in try-with-resources block. This means, that close() method was called on both directly after try block, as if there were finally{fileReader.close();bufferedReader.close()}
.
Upvotes: 2