2011-03-07 11 views
6

Poniższy kod generuje numer EOFException. Dlaczego?Wyjątek Java Mysterious EOF z readObject

public static Info readInfoDataFromFile(Context context) { 
    Info InfoData = null; 
    FileInputStream fis = null; 
    ObjectInputStream ois = null; 
    Object object = null; 

    if (context.getFileStreamPath("InfoFile.dat").exists()) { 
     try { 
      fis = context.openFileInput("InfoFile.dat"); 
      ois = new ObjectInputStream(fis); 
      Object temp; 
      try { 
       // here it throws EOF exception in while loop 
       while ((temp = ois.readObject()) != null) { 
        object = temp; 
       } 
      } catch (NullPointerException npe) { 
       npe.printStackTrace(); 
      } catch (EOFException eof) { 
       eof.printStackTrace(); 
      } catch (FileNotFoundException fnfe) { 
       fnfe.printStackTrace(); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       if (ois != null) { 
        ois.close(); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      try { 
       if (fis != null) { 
        fis.close(); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

StackTrace:

03-07 14:29:01.996: WARN/System.err(13984): java.io.EOFException 
03-07 14:29:01.996: WARN/System.err(13984):  at java.io.DataInputStream.readByte(DataInputStream.java:131) 
03-07 14:29:01.996: WARN/System.err(13984):  at java.io.ObjectInputStream.nextTC(ObjectInputStream.java:628) 
03-07 14:29:01.996: WARN/System.err(13984):  at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:907) 
03-07 14:29:01.996: WARN/System.err(13984):  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2262)03-07 14:29:01.996: WARN/System.err(13984):  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2217) 
03-07 14:29:01.996: WARN/System.err(13984):  at 
+2

Javadoc: 'Każda próba odczytu danych obiektów, które przekracza granice danych niestandardowych napisanych przez odpowiednią metodą writeObject spowoduje OptionalDataException zostać wyrzucony z wartością pola EOF z true' – malinois

+0

tak już ją przeczytać ale jak tego uniknąć? –

Odpowiedz

9

Zależy ile obiektów plik zawiera. Jeśli ma tylko jeden obiekt, możesz deserializować w jednym kroku.

try { 
    Object temp = ois.readObject(); 
} 
catch(Exception e) { 
    //handle it 
} 
+2

tak, ale to powoduje błąd EOF .. dlaczego? –

+0

uprzejmie zobacz śledzenie stosu. –

+6

@Aizaz: dlaczego oczekujesz, że 'readObject()' zwróci 'null' na końcu pliku? Nie ma, jest określony, aby zawsze zwracać obiekt lub generować wyjątek. Więc jeśli nie jawnie serializujesz 'null', nie powinieneś oczekiwać, że' readObject() 'zwróci' null'. –

2

Definicja readObject() na ObjectInputStream nie precyzuje, że powróci null gdy zostanie osiągnięty koniec strumienia. Zamiast tego zostanie zgłoszony wyjątek, jeśli spróbujesz odczytać dodatkowy obiekt poza końcem pliku.

+0

to jak wykryć, jesteśmy na końcu pliku? Mam na myśli, jak uniknąć wyjątku EOF? –

+0

Zapisz w pliku informacje, ile obiektów możesz oczekiwać, lub obsłuż wyjątek EOF. Pamiętaj, że wyjątki nie są koniecznie "awariami", ale mogą być używane jako sposób propagowania zmian stanu przez stos. – AndyT

+0

@Aizaz: * złap * to! – EJP

4

Przede wszystkim readObject() zwraca tylko null jeśli napisał null do strumienia podczas tworzenia go. Jeśli nie ma więcej danych w strumieniu, wyświetli się EOFException.

Jeśli nie spodziewasz się EOF, powodem prawdopodobnie jest to, że strumień jest uszkodzony. Może się to zdarzyć, jeśli zapomnisz zamknąć go po zapisaniu danych.

+0

to jak wykryć, jesteśmy na końcu pliku? Mam na myśli, jak uniknąć wyjątku EOF? –

+4

@Aizaz: EOFException ci to mówi.Sprawdzony wyjątek powinien zostać przechwycony i zbadany pod kątem przepływu sterowania. Nie są to błędy, ale dodatkowe kody powrotne. Czasami. Jeśli jest używany prawidłowo. Tak nie jest w przypadku większości Wyrażeń IOE. Ale popraw EOFException. ... Ahem. Innym rozwiązaniem jest zapisanie liczby obiektów w strumieniu przed obiektami, dzięki czemu można zapętlić znaną liczbę razy. Lub umieść obiekty w kontenerze, tak jak listę lub tablicę, i załaduj kontener. –

+0

Myślę, że to jest poprawna odpowiedź: @Aizaz - readObject() odczyta cały plik naraz i deserializuje go dla ciebie. Tylko upewnij się, że dzwonisz tylko raz, a nie w pętli. - adarshr 18 godzin temu –

5

Miałem ten sam tajemniczy EOFException i była to tylko ścieżka klasy Object do wysłania przez ObjectOutputStream do ObjectInputStream. Muszą mieć tę samą ścieżkę (ta sama nazwa pakietu i oczywiście ta sama nazwa klasy).