2017-01-03 1 views
1

향후 워크 아웃을 계획하는 데 도움이되는 작은 프로그램을 작성 중입니다. 나는 거의 끝내고 있지만 저축과 적재는 나에게 약간의 문제를주고있다. 이 프로그램은 여러 가지 특성 (예 : Dat 및 일부 int 및 double 값)을 보유하고있는 "ride"(사용자 정의 클래스) 객체 목록과 함께 작동합니다.Java 프로그램에서 사용자 정의 오브젝트 저장 및로드

지금 저는 두 가지 방법, "보호기" 및 "로더":

public void saver() { 
     try{ // Catch errors in I/O if necessary. 
      // Open a file to write to, named SavedObj.sav. 
      FileOutputStream saveFile=new FileOutputStream("SaveObj.sav"); 
      // Create an ObjectOutputStream to put objects into save file. 
      ObjectOutputStream save = new ObjectOutputStream(saveFile);    
      // Now we do the save. 
      for (int x = 0; x < rides.size(); x++) { 
       save.writeObject(rides.get(x).getDate()); 
       save.writeObject(rides.get(x).getMinutes()); 
       save.writeObject(0); 
       save.writeObject(rides.get(x).getIF()); 
       save.writeObject(rides.get(x).getTss()); 
      } 

      // Close the file. 
      save.close(); // This also closes saveFile. 
     } 
     catch(Exception exc){ 
      exc.printStackTrace(); // If there was an error, print the info. 
     } 

    } 

    public void loader() { 
     try{ 
      // Open file to read from, named SavedObj.sav. 
      FileInputStream saveFile = new FileInputStream("SaveObj.sav"); 

      // Create an ObjectInputStream to get objects from save file. 
      ObjectInputStream save = new ObjectInputStream(saveFile); 
      Ride worker; 
      while(save.available() > 0) { 
       worker = new Ride((Date)save.readObject(), (int)save.readObject(), (double)save.readObject(), (double)save.readObject(), (int)save.readObject()); 
       addRide(worker.getDate(), worker.getMinutes(), 0, worker.getIF(), worker.getTss()); 
      } 

      // Close the file. 
      save.close(); // This also closes saveFile. 
      } 
      catch(Exception exc){ 
       exc.printStackTrace(); // If there was an error, print the info. 
     } 
    } 

프로그램을 실행할 때 "저장"또는 "로드"도 오류를 반환하지 않습니다. .sav 파일은 프로그램이 없을 때 만들어지며 프로그램을 실행할 때마다 편집됩니다. 그러나이 프로그램은 이전 세션의 데이터를 복원하지 않습니다. 자세한 정보가 필요한 경우 알려 주시기 바랍니다. 도움에 미리 감사드립니다!

+1

.sav 파일에 내용이 있습니까? – CraigR8806

+0

'while (save.available()> 0) 아래의 로더에 중단 점을 추가하는 것은 어떻습니까? 코드가'worker ='로 시작하는 라인에 닿습니까? 그렇다면 여기서 무엇이 일어나고 있습니까? – ControlAltDel

+0

저장 파일에 "내용"이 있습니다. 그러나 프로그램을 업데이트 할 때 변경되지 않는 것 같습니다. 로더 내부에 system.out.print를 추가했는데 출력되지 않습니다. – e6r339b

답변

0

차단하지 않고 읽을 수있는 바이트 수를 반환하는 available()을 사용하지 마십시오. 모든 바이트를 읽은 것은 아닙니다.

개체가 결코 null이 아닌 경우 Object readObject()을 사용하여 모든 데이터가 입력 스트림에서 읽혔는지 확인할 수 있습니다. 모든 데이터가 있다면 읽어 값이 null이 될 수있는 경우

Date date = null; 
while((date = (Date)save.readObject()) != null) { 
    worker = new Ride(date, (int)save.readObject(), (double)save.readObject(), (double)save.readObject(), (int)save.readObject()); 
    addRide(worker.getDate(), worker.getMinutes(), 0, worker.getIF(), worker.getTss()); 
} 

그렇지 않으면, 당신이 직접 Ride 개체 또는이와 null
이 될 수 단일 필드보다는 직렬화하는 모든 필드를 포함하는 클래스를 직렬화 할 수 체크는 알고 Object readObject()으로 읽을 수 있습니다.

+0

고마워, 고쳐 줬어! – e6r339b

+0

당신은 환영합니다 :) – davidxxx

0

available()을 조건으로 사용하지 마십시오. 단지 지연없이 즉시 읽을 수있는 바이트가 있는지 여부를 알려주며 스트림이 끝났음을 의미하지는 않습니다.

또한 Object 및 File 스트림 사이에 BufferedInputStream 및 BufferedOutputStream을 추가해야합니다. 거의 항상 좋은 생각입니다.

문제를 해결하려면 e. 지. 먼저 얼마나 많은 객체가 파일에 있는지를 알려주는 save 메소드에 정수를 작성하고로드시 해당 정수를 읽은 다음이 양의 루프에 대해 간단하게 만듭니다.

또는 행에 PushbackInputStream을 던져 넣은 다음 EOF 수표로 read() 메서드를 사용할 수 있습니다. EOF에서 -1을 반환하고 읽기를 중단 할 수 있습니다. 그것이 다른 것을 반환한다면, 당신은 unread() 바이트를 읽고 위에 놓인 ObjectInputStream을 사용하십시오.