2017-11-11 8 views
2

"Toy Language"のJavaでミニインタープリタを作成する必要があります。このプロジェクトでは、プライベートフィールドとして持つクラスであるFileTableを含める必要がありますFILEDATAがあるHashMap<Integer, FileData>、:またJava BufferedReaderを使用してファイルから読み込むことはできません:ストリームが閉じた

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

    // methods... 
} 

は、私は方法execute(String fileName)を持つ別のクラスのOpenRFileを持っています。このメソッドは、指定された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、ちょうどFileTableからFileDataオブジェクトを取得し、BufferedReaderオブジェクトのメソッドreadLine()を呼び出し、これは私がSteam closedエラーを取得する瞬間ですexecute方法。

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オブジェクトからファイル名を取得し、新しいBufferedReaderオブジェクトを作成した場合、それが動作します。しかし、既に私が持っているオブジェクトに直接readLine()を呼び出そうとすると、エラーが出ます。

+1

あなたは他の場所で閉じたストリームから読み込もうとしています。関連するコードがなければ、私たちはあなたをさらに助けることはできません。 –

+0

私はBufferedReaderオブジェクトに対して 'close()'メソッドを呼び出さない。だから私は何が問題なのか理解できません。 – Xyntell

+0

ようこそStackoverflowへ、[How To Ask](https://stackoverflow.com/help/how-to-ask)をお読みください。 [MCVEの作成方法](https://stackoverflow.com/help/mcve)に特に注意してください。良い質問を投稿するために、より多くの努力が必要です。読みやすく、理解しやすく、トピック上にあるものです(https://stackoverflow.com/help/on-topic) - その可能性は高いです関連する人々を惹きつけ、あなたはもっと早く助けを得るでしょう。がんばろう! – alfasin

答えて

2

try-with-resourcesブロックにBufferedReaderとFileReaderを作成しました。つまり、close()メソッドは、tryブロックの直後に、finally{fileReader.close();bufferedReader.close()}のように両方とも呼び出されました。

関連する問題