2017-11-11 3 views
2

Ich muss einen Mini-Interpreter in Java für eine "Spielzeugsprache" erstellen und in diesem Projekt muss ich eine FileTable einschließen, die eine Klasse mit privatem Feld ist ein HashMap<Integer, FileData>, wo Filedata ist:Java BufferedReader kann nicht aus einer Datei lesen: Stream geschlossen

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

    // methods... 
} 

auch habe ich eine andere Klasse OpenRFile die execute(String fileName) eine Methode hat. Diese Methode erstellt ein BufferedReader-Objekt für den angegebenen Dateiname und ein FileData-Objekt, das in der FileTable hinzugefügt wird.

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 + ");"; 
    } 
} 

Später, in einer anderen Klasse: ReadFile, wobei das Verfahren execute ruft nur das FileData Objekt aus den FileTable und ruft die Methode readLine() auf das BufferedReader Objekt, und das ist der Moment, als ich die Steam closed Fehler.

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 + ")"; 
    } 
} 

Wenn ich die Dateinamen aus dem FileData Objekt abrufen und ein neues BufferedReader Objekt erstellen, es funktioniert. Aber wenn ich versuche, readLine() direkt auf dem Objekt anzurufen, das ich bereits habe, erhalte ich den Fehler.

+1

Sie versuchen, von einem Stream zu lesen, den Sie anderswo geschlossen haben. Ohne entsprechenden Code können wir Ihnen nicht weiter helfen. –

+0

Ich rufe die Methode 'close()' für das BufferedReader-Objekt nicht auf. Deshalb kann ich nicht verstehen, was das Problem ist. – Xyntell

+0

Willkommen bei Stackoverflow, lesen Sie bitte [Wie zu fragen] (https://stackoverflow.com/help/how-to-ask). Achten Sie besonders auf [So erstellen Sie MCVE] (https://stackoverflow.com/help/mcve). Je mehr Aufwand Sie in die Veröffentlichung einer guten Frage investieren: eine, die leicht zu lesen und zu verstehen ist und die [zum Thema] (https://stackoverflow.com/help/on-topic) ist - die Chancen stehen höher Sie werden die relevanten Leute anziehen und Sie werden schneller Hilfe bekommen. Viel Glück! – alfasin

Antwort

2

Sie haben BufferedReader und FileReader in try-with-resources Block erstellt. Dies bedeutet, dass die Methode close() direkt nach dem try-Block aufgerufen wurde, als ob es finally{fileReader.close();bufferedReader.close()} gäbe.