que - Java FileInputStream ObjectInputStream llega al final del archivo EOF
objectinputstream para que sirve (8)
readObject()
no devuelve null
en EOF. Podría capturar la EOFException
e interpretarla como EOF, pero esto no detectaría distinguir un EOF normal de un archivo que se ha truncado.
Un mejor enfoque sería usar algunos metadatos. Es decir, en lugar de preguntarle a ObjectInput
cuántos objetos hay en la secuencia, debe almacenar el conteo en alguna parte. Por ejemplo, puede crear una clase de metadatos que registre el recuento y otros metadatos y almacene una instancia como el primer objeto en cada archivo. O puede crear una clase de marcador EOF especial y almacenar una instancia como el último objeto en cada archivo.
Estoy tratando de leer el número de línea en un archivo binario usando readObject, pero obtengo IOException EOF. ¿Estoy haciendo esto de la manera correcta?
FileInputStream istream = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(istream);
/** calculate number of items **/
int line_count = 0;
while( (String)ois.readObject() != null){
line_count++;
}
No, necesitas saber cuántos objetos hay en el archivo binario. Puede escribir el número de objetos al principio del archivo (usando writeInt por ejemplo) y leerlo mientras lo carga.
Otra opción es llamar a ois.available () y repetir hasta que devuelva 0. Sin embargo, no estoy seguro si esto es 100% seguro.
Parece que el problema está con los datos que usted escribió. Suponiendo que los datos se escriben como se espera por este código, no debería haber un problema.
(Veo que está leyendo String
s. Este ObectInputStream
no es para leer archivos de texto. Use InputStreamReader
y BufferedReader.readLine
para eso. De manera similar, si ha escrito el archivo con DataOutputSteam.writeUTF
, DataOutputSteam.writeUTF
con DataInputStream.readUTF
)
La mejor manera posible de finalizar el ciclo podría hacerse agregando un objeto nulo al final. Mientras se lee el objeto nulo, se puede usar como condición de frontera para salir del ciclo. La captura de la EOFException también resuelve el propósito, pero toma unos pocos m
El método disponible de ObjectInputStream no se puede usar para terminar el ciclo ya que devuelve 0 incluso si hay objetos para leer en un archivo. Escribir un nulo en un archivo no parece ser una buena solución, ya que los objetos pueden ser nulos y luego se interpretarían como el final del archivo. Creo que capturar la excepción EOF para terminar los bucles es una práctica mejor ya que si se produce la excepción EOFException (ya sea porque llegaste al final del archivo o por algún otro motivo), tienes que terminar el bucle de todos modos.
Es curioso que la API no proporcione una solución más elegante para esto. Creo que la EOFException
funcionaría, pero siempre me han alentado para ver las excepciones como eventos inesperados, mientras que aquí a menudo se espera que el flujo de objetos llegue a su fin.
Traté de evitar esto escribiendo un tipo de objeto "marcador" para indicar el final de la secuencia de objeto:
import java.io.Serializable;
public enum ObjectStreamStatus implements Serializable {
EOF
}
Luego, en el código que lee el objeto que revisé para este objeto EOF en el bucle de lectura de objetos.
Tuve el mismo problema hoy. Aunque la pregunta es bastante antigua, el problema persiste y no se proporcionó una solución limpia. Ignorar la EOFException
debe evitarse, ya que puede producirse cuando algún objeto no se guardó correctamente. La escritura nula obviamente le impide utilizar valores nulos para otros fines. Finalmente, usar available()
en la secuencia de objetos siempre devuelve cero, ya que se desconoce el número de objetos.
Mi solución es bastante simple. ObjectInputStream
es solo un contenedor para alguna otra transmisión, como FileInputStream. Aunque ObjectInputStream.available ()
devuelve cero, FileInputStream.available devolverá algún valor.
FileInputStream istream = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(istream);
/** calculate number of items **/
int line_count = 0;
while( istream.available() > 0) // check if the file stream is at the end
{
(String)ois.readObject(); // read from the object stream,
// which wraps the file stream
line_count++;
}
No. Captura EOFException
y EOFException
para finalizar el ciclo.