Question

Je suis en train de lire le numéro de la ligne dans un fichier binaire en utilisant readObject, mais je reçois IOException EOF. Suis-je le faire de la bonne façon?

    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++;
    }
Était-ce utile?

La solution

readObject() ne retourne pas null à EOF. Vous pouvez attraper le EOFException et l'interpréter comme EOF, mais cela ne permettrait pas de détecter une distinction EOF normale à partir d'un fichier qui a été tronqué.

Une meilleure approche serait d'utiliser des méta-données. C'est, plutôt que de demander l'ObjectInput nombre d'objets dans le flux, vous devez stocker quelque part le comptage. Par exemple, vous pouvez créer une classe méta-données qui enregistre le nombre et d'autres méta-données et stocker une instance comme le premier objet dans chaque fichier. Ou vous pouvez créer une classe spéciale marqueur EOF et stocker une instance comme le dernier objet dans chaque fichier.

Autres conseils

J'ai eu le même problème aujourd'hui. Bien que la question est assez vieux, les restes de problème et il n'y avait pas de solution propre fournie. Ignorant EOFException doit être évitée car elle peut être levée lorsque un objet n'a pas été correctement enregistré. null L'écriture vous empêche évidemment d'utiliser des valeurs nulles pour d'autres fins. Enfin en utilisant available() sur les objets flux retourne toujours zéro, comme le nombre d'objets est inconnu.

Ma solution est assez simple. ObjectInputStream est juste un wrapper pour un autre cours d'eau, comme FileInputStream. Bien que le rendement ObjectInputStream.available () zéro, le FileInputStream.available retourne une valeur.

   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++;
   }
Non

. Catch EOFException et l'utiliser pour mettre fin à la boucle.

Si vous écrivez un objet nul à la fin du fichier, quand vous le lisez en arrière, vous obtiendrez une valeur NULL et peut mettre fin à votre boucle.

Il suffit d'ajouter: out.writeObject (null);

lorsque vous sérialiser les données.

Il est curieux que l'API ne fournit pas une solution plus élégante à ce sujet. Je suppose que le EOFException fonctionnerait, mais je l'ai toujours été encouragé à voir des exceptions comme des événements inattendus alors qu'ici vous attendez souvent le flux d'objet pour arriver à une fin.
j'ai essayé de contourner ce problème en écrivant une sorte d'objet « marqueur » pour signifier la fin du flux d'objet:

import java.io.Serializable;

public enum ObjectStreamStatus implements Serializable {
    EOF
}


Ensuite, dans le code de lecture de l'objet que j'ai vérifié pour cet objet EOF dans la boucle de lecture objet.

Non, vous devez savoir combien d'objets il y a dans le fichier binaire. Vous pouvez écrire le nombre d'objets au début du fichier (en utilisant writeInt par exemple) et le lire en le chargeant.

Une autre option est d'appeler ois.available () et la boucle jusqu'à ce qu'il retourne 0. Cependant, je ne suis pas sûr que ce soit 100% sûr.

Il semble que le problème est avec les données que vous rédigeai. Si l'on suppose que les données sont écrites comme prévu par le présent code, il ne devrait pas être un problème.

(je vois que vous lisez Strings. Ce ObectInputStream n'est pas pour la lecture de fichiers texte. Utilisez InputStreamReader et BufferedReader.readLine pour cela. De même, si vous avez écrit le fichier avec DataOutputSteam.writeUTF, lu avec DataInputStream.readUTF)

La méthode disponible de ObjectInputStream ne peut pas utilisé pour terminer la boucle car il renvoie 0 même s'il y a des objets à lire dans un fichier. L'écriture d'un null dans un fichier doen't semble être une bonne solution non plus car les objets peuvent être nuls qui serait alors interprété comme la fin du fichier. Je pense attrapant le EOFException de mettre fin aux boucles est une meilleure pratique car si EOFException se produit (soit parce que vous avez atteint la fin du fichier ou une autre raison), vous devez terminer la boucle de toute façon.

La meilleure manière de mettre fin à la boucle peut se faire par addition d'un objet nul à la fin. Lors de la lecture de l'objet nul peut être utilisé comme une condition aux limites pour sortir de la boucle. Attraper le EOFException résout aussi le but mais il faut quelques m

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top