2011-03-07 51 views
6

El siguiente código produce un EOFException. ¿Porqué es eso?Excepción EOF misteriosa de Java con 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: 'Cualquier intento de leer datos de objeto que excede los límites de los datos personalizados escritos por el método writeObject correspondiente provocará un OptionalDataException a ser lanzado con un valor de campo de EF true' – malinois

+0

sí ya he leído pero cómo evitarlo? –

Respuesta

9

depende del número de objetos de su archivo contiene. Si tiene un solo objeto, puede deserializar en un solo paso.

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

sí, pero arroja el error EOF ... ¿por qué? –

+0

amablemente vea el rastro de la pila. –

+6

@Aizaz: ¿por qué esperas que 'readObject()' devuelva 'null' al final del archivo? No, está especificado para devolver siempre el objeto o lanzar una excepción. A menos que haya serializado explícitamente 'null', no debería esperar que' readObject() 'devuelva' null'. –

2

La definición de readObject() en ObjectInputStream no especifica que le proporcione null cuando se alcanza el final del flujo. En cambio, se lanza una excepción si intenta leer un objeto adicional más allá del final del archivo.

+0

entonces cómo detectar en que estamos al final del archivo? Me refiero a cómo evitar la excepción EOF? –

+0

O almacena información en el archivo que te dice cuántos objetos esperar o maneja la excepción EOF correctamente. Recuerde que las excepciones no son necesariamente 'fallas', pero pueden usarse como una forma de propagar cambios de estado a través de la pila. – AndyT

+0

@Aizaz: * atrapa * it! – EJP

4

En primer lugar, readObject() sólo devuelve null si escribió null a la corriente cuando se crea. Si no hay más datos en la transmisión, lanzará un EOFException.

Si no espera el EOF, es probable que la secuencia esté dañada. Esto puede suceder si olvida cerrarlo después de escribirle datos.

+0

entonces cómo detectar en que estamos al final del archivo? Me refiero a cómo evitar la excepción EOF? –

+4

@Aizaz: la EOFException te dice eso.La excepción controlada se debe capturar y examinar para el flujo de control. No son errores sino códigos de retorno adicionales. A veces. Si se usa correctamente Lo cual no es el caso para la mayoría de IOExceptions. Pero correcto para EOFException. ... ejem. Otra solución es escribir la cantidad de objetos en la secuencia antes de los objetos, de modo que pueda hacer un ciclo una cantidad conocida de veces. O coloque los objetos en un contenedor como una lista o una matriz y cargue el contenedor en su lugar. –

+0

Creo que esta es la respuesta correcta: @Aizaz - readObject() leerá todo el archivo a la vez y lo deserializará por usted. Solo asegúrate de llamarlo solo una vez y no en un bucle. - adarshr hace 18 horas –

5

Tenía el mismo misterioso EOFException y era solo la ruta de la clase de objetos para enviar a través del ObjectOutputStream al ObjectInputStream. Deben tener la misma ruta (el mismo nombre de paquete y, por supuesto, el mismo nombre de clase).