2017-10-25 4 views
0

私はバイナリランダムアクセスファイルにデータ(文字列とint)を書き込み、別のクラスでデータを読み込むプロジェクトを持っています。私が持っている問題は、ファイルを繰り返し処理し、特定の順序(int、String、String、int)でデータを読み取ろうとしていることです。しかし、文字列はさまざまなバイトサイズです。randomaccesfileからの書き込み/読み込み

私はEOFExceptionを受け取りましたが、理由を理解できません。

ここにデータを書き込むクラスです。要件の一部は、文字列のバイト数を制限し、超過した場合にユーザー定義の例外をキャッチすることです。

import java.io.RandomAccessFile; 
import java.io.IOException; 
import java.io.FileNotFoundException; 
import java.util.Arrays; 
import java.util.ArrayList; 
import java.io.File; 

public class QuestionBank { 
    private RandomAccessFile file; 
    private ArrayList <Questions> listQuestions; 

    public QuestionBank(){ 
     file = null; 
     listQuestions = new ArrayList<Questions>();  
    } 

    public void storeQuestion (Questions ques) throws IOException { 

     ques = new Questions(ques.getQuesIDNum(), ques.getQuestion(), ques.getAnswer(), ques.getValue()); 

     listQuestions.add(ques); 

     byte[] quesBytes = ques.getQuestion().getBytes("UTF-8"); 
     byte[] ansBytes = ques.getAnswer().getBytes("UTF-8"); 

     try { 
      file = new RandomAccessFile(new File("Question.bin"), "rw"); 

      long fileSize = file.length(); 

      file.seek(fileSize); 

      file.writeInt(ques.getQuesIDNum()); 

      file.writeUTF(ques.getQuestion()); 

      for (int i = 0; i <= 50 - ques.getQuestion().length(); i++){ 
       file.writeByte(50); 
       }    
      if (quesBytes.length > 50) { 
       throw new ByteSizeException("Question has too many bytes"); 
       } 

      file.writeUTF(ques.getAnswer()); 

      for (int i = 0; i <= 20 - ques.getAnswer().length(); i++){ 
       file.writeByte(20); 
       } 
      if (ansBytes.length > 20) { 
       throw new ByteSizeException("Answer has too many bytes"); 
       } 

      file.writeInt(ques.getValue()); 

      file.close(); 
      } catch (IOException e) { 

      System.out.println("I/O Exception Found"); 


      } catch (ByteSizeException eb) { 

      System.out.println("String has too many bytes"); 
      }     
    } 

ファイルを読み込むクラスです。

import java.util.ArrayList; 
import java.util.Random; 
import java.io.RandomAccessFile; 
import java.io.IOException; 
import java.io.FileNotFoundException; 

import java.io.File; 

public class TriviaGame { 
    public static final int RECORD = 78; 
    private ArrayList<Questions> quesList; 
    private int IDNum; 
    private String question; 
    private String answer; 
    private int points; 

    public TriviaGame() { 
     quesList = new ArrayList<Questions>(); 
     IDNum = 0; 
     question = ""; 
     answer = ""; 
     points = 0; 
    } 

    public void read(){ 
     try { 
      RandomAccessFile file; 

      file = new RandomAccessFile(new File("Question.bin"), "r"); 
      long fileSize = file.length();   
      long numRecords = fileSize/RECORD; 

      file.seek(0); 

      for (int i = 0; i < numRecords; i++){ 
      IDNum = file.readInt(); 
      question = file.readUTF();          
      answer = file.readUTF();            
      points = file.readInt(); 

      System.out.println("ID: " + IDNum + " Question: " + question + " Answer: " + answer + " Points: " + points); 
     } 
    file.close(); 

    } catch (IOException e) { 
     System.out.println(e.getClass()); 
     System.out.println("I/O Exception found"); 
    } 
    } 
} 

おかげでここ

+0

あなたは**確実に**データの書き込みは 'RECORD'の長さを超えていませんか? – markspace

+0

全体のスタックトレースをポストする方が良いでしょう。 – Alex

+0

これは壊れたようです: 'file.writeByte(50);'あなたは0を書き込むつもりはないと確信していますか? – markspace

答えて

0
file.writeUTF(ques.getQuestion()); 

あなたは質問を書かれています。

for (int i = 0; i <= 50 - ques.getQuestion().length(); i++){ 
    file.writeByte(50); 
}    
if (quesBytes.length > 50) { 
    throw new ByteSizeException("Question has too many bytes"); 
} 

ここで何らかの理由で、質問を50バイトに埋めています。削除します。答えと同じです。これらの両方を読むにはreadUTF()を使用しているため、必要なのはwriteUTF()です。パディングは必要ありません。

それともあなたはこのパディングを主張するならば、あなたは読むとき、それをスキップする必要があります:最初のreadUTF()した後、あなたはパディングをスキップする必要があります。

+0

ありがとう、私はそこにread()メソッドの反復を助けるためにパディングを入れました。私はファイルからデータを解析する他の方法を探していましたが、それは論理的に見えました。コードは完全ではありませんが、ファイルから5つのランダムな質問を読み込む方法を修正するつもりです。私のロジックは、私は文字列をバイトで埋める場合、各文字列は50バイトです。文字列と空のバイト。しかし、あなたは正しいです、私は残りのバイトをスキップする必要があります。 – Jengland

関連する問題