IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entrée/Sortie Java Discussion :

ObjectInputStream : test d'arrêt EOF?


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut ObjectInputStream : test d'arrêt EOF?
    Salut,

    Comment faire pour lire un fichier jusqu'au bout en récupérant les objets qui sont dedans, en s'arrêtant proprement?

    Je n'ai pas trouvé d'autres solutions que de faire ça, ce qui ne me convient absolument pas (un while(true) pour une boucle non infinie, je n'aime pas):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename));
            try {
                while(true) {
                    try {
                        Object read = ois.readObject();
                        ...
                    } catch(ObjectStreamException ose) {} catch(ClassNotFoundException cnfe) {}
                }
            } catch(EOFException oef) { /* pour sortir de la boucle */ }
     
        } catch(FileNotFoundException fnfe) { ... } catch(IOException ioe) { ... }

  2. #2
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Par défaut
    Tu peux utiliser la méthode available() de ton ObjectInputStream.
    Au passage, n'oublie pas de fermer le flux dans un bloc finally
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    try {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename));
        try {
            while(ois.available() > 0) {
                 try {
                    Object read = ois.readObject();
                    ...
                 } catch(ObjectStreamException ose) {}
                 catch(ClassNotFoundException cnfe) {}
        } finally {
             ois.close();
        }     
    } catch(FileNotFoundException fnfe) { 
           ... 
    } catch(IOException ioe) { 
           ... 
    }
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  3. #3
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Merci, je vais essayer ça

    Pour le bloc finally, c un peu bête que le close puisse lever une IOException:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
            finally {
                if(oos != null) {
                    try {
                        oos.close();
                    } catch(IOException ioe) {}
                }
            }

  4. #4
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    et dans le cas du while(ois.available() > 0), il faut tester quand même EOFException (on peut arriver à la fin du fichier avant la fin de chargement d'un objet si le fichier est corrompu)?

    EDIT: J'ai rien dit, FileNotFoundException < IOException

  5. #5
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par le y@m's
    Tu peux utiliser la méthode available() de ton ObjectInputStream.
    Attention car la valeur renvoyé par available renvoit le nombre de byte disponible sans que la méthode read() ne soit bloqué... mais cela ne veut pas forcément dire que l'on a atteint la fin du flux...

    Citation Envoyé par le y@m's
    Au passage, n'oublie pas de fermer le flux dans un bloc finally
    +1

    Et pas de catch() vide !!!! J'espère que ce n'est pas le cas dans le vrai code




    Sinon pour revenir à ton problème, tu peux utiliser un booleen qui contient le status EOF, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
            try {
                FileInputStream fis = new FileInputStream(filename);
                try {
                    ObjectInputStream ois = new ObjectInputStream(fis);
                    try {
                        boolean hasObject = true;
                        while(hasObject) {
                            try {
                                Object read = ois.readObject();
                                // ...
                            } catch(EOFException oef) { hasObject = false; }
                        }
                    } finally {
                        ois.close();
                    }
                } finally {
                    fis.close();
                }
     
            } catch(IOException  e) {
                e.printStackTrace();
            }
            // etc...

    Sinon pourquoi ne pas serialiser un tableau ou une List qui contiendrait tout le contenu ? Tu n'aurais alors qu'un seul readObject à lire...


    Citation Envoyé par ®om
    Pour le bloc finally, c un peu bête que le close puisse lever une IOException:
    Il vaut mieux utiliser un try/finally à l'intérieur du try/catch plutôt que de faire un try/catch/finally : http://www.developpez.net/forums/sho...4&postcount=69


    a++

  6. #6
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par adiGuba
    Et pas de catch() vide !!!! J'espère que ce n'est pas le cas dans le vrai code
    Non non t'inquiète


    Citation Envoyé par adiGuba
    Sinon pourquoi ne pas serialiser un tableau ou une List qui contiendrait tout le contenu ? Tu n'aurais alors qu'un seul readObject à lire...
    Parce qu'en fait c'est pour sauver l'ensemble des configurations des modules... même celles que peuvent rajouter les plug-ins... Et si une renvoie un "NotSerializableException", rien ne se chargerait, alors que là on peut quand même changer les autres

    Citation Envoyé par adiGuba
    Il vaut mieux utiliser un try/finally à l'intérieur du try/catch plutôt que de faire un try/catch/finally : http://www.developpez.net/forums/sho...4&postcount=69
    Mouais, mais je ne trouve pas, car les actions que l'on fait sur le catch(IOException) ne sont pas forcément les mêmes que si le .close() échoue...

    Voici ce que donne ma méthode maintenant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
        /**
         * Charge les configurations actuelles à partir du fichier de configuration.
         */
        public synchronized void load() {
            if(ModuleLoader.getModuleLoader().loadingIsComplete())
                throw new UnsupportedOperationException("Impossible de lancer un nouveau chargement.");
     
            assert map.isEmpty() : "Aucune configuration ne doit être déjà présente.";
     
            ObjectInputStream ois = null;
            try {
                ois = new ObjectInputStream(new FileInputStream(configFilename));
     
                /* Indique s'il reste des objets à lire. */
                boolean hasObject = true;
     
                do {
                    try {
                        Object read = ois.readObject();
                        if(read instanceof Configuration) {
                            Configuration config = (Configuration) read;
                            ModuleLoader.getModuleLoader().log("Chargement de la configuration " + config.getId() + "...");
                            register(config);
                        } else {
                            Logger.getLogger("MyFreeTV").severe("Un objet du fichier de configuration n'est pas une configuration.");
                        }
                    } catch(EOFException oef) {
                        hasObject = false;
                    } catch(ObjectStreamException ose) {
                        Logger.getLogger("MyFreeTV").severe("Une configuration n'a pas pu être chargée (erreur d'I/O).");
                    } catch(ClassNotFoundException cnfe) {
                        Logger.getLogger("MyFreeTV").severe("Une configuration n'a pas pu être chargée (classe non trouvée).");
                    }
                } while(!hasObject);
     
            } catch(FileNotFoundException fnfe) {
                /* Le fichier n'existe pas... ce qui est normal lors du premier chargement du programme. */
            } catch(IOException ioe) {
                Logger.getLogger("MyFreeTV").severe("Erreur d'I/O dans le fichier de configuration.");
            } finally {
                if(ois != null) {
                    try {
                        ois.close();
                    } catch(IOException ioe) {}
                }
            }
        }

  7. #7
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par ®om
    Non non t'inquiète
    AAh je suis rassuré



    Citation Envoyé par ®om
    Parce qu'en fait c'est pour sauver l'ensemble des configurations des modules... même celles que peuvent rajouter les plug-ins... Et si une renvoie un "NotSerializableException", rien ne se chargerait, alors que là on peut quand même changer les autres
    En effet c'est une bonne raison


    Citation Envoyé par ®om
    Mouais, mais je ne trouve pas, car les actions que l'on fait sur le catch(IOException) ne sont pas forcément les mêmes que si le .close() échoue...
    Mouais... je n'ai jamais vraiment eu le cas...
    Et je ne pense pas que ce soit génant dans ton cas de loggé les erreurs qui pourrait survenir à la fermeture... surtout qu'elle ne sont pas vraiment fréquente...


    Enfin, et parce que je suis très chiant : il y a un cas où tu ne fermes pas correctement le fichier !
    En effet comme le constructeur d'ObjectInputStream commence à lire le flux pour vérifier qu'il s'agit bien d'un fichier sérialisé, tu peux avoir une StreamCorruptedException...


    Donc dans le cas où le fichier ouvert n'est pas correct, la référence ois est null car le constructeur aura généré une exception, et tu n'appelles pas le close() (normal). Or tu as ouvert un FileInputStream qui ne sera pas fermé, et dont tu auras perdu la référence...

    hé hé hé hé (je sais je suis sadique !)

    a++

  8. #8
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par adiGuba
    Enfin, et parce que je suis très chiant : il y a un cas où tu ne fermes pas correctement le fichier !
    En effet comme le constructeur d'ObjectInputStream commence à lire le flux pour vérifier qu'il s'agit bien d'un fichier sérialisé, tu peux avoir une StreamCorruptedException...


    Donc dans le cas où le fichier ouvert n'est pas correct, la référence ois est null car le constructeur aura généré une exception, et tu n'appelles pas le close() (normal). Or tu as ouvert un FileInputStream qui ne sera pas fermé, et dont tu auras perdu la référence...

    hé hé hé hé (je sais je suis sadique !)
    Bien vu !!

    C'est mieux comme ça?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
        /**
         * Charge les configurations actuelle à partir du fichier de configuration.
         */
        public synchronized void load() {
            if(ModuleLoader.getModuleLoader().loadingIsComplete())
                throw new UnsupportedOperationException("Impossible de lancer un nouveau chargement.");
     
            assert map.isEmpty() : "Aucune configuration ne doit être déjà présente.";
     
            ObjectInputStream ois = null;
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(configFilename);
                ois = new ObjectInputStream(fis);
     
                /* Indique s'il reste des objets à lire. */
                boolean hasObject = true;
     
                do {
                    try {
                        Object read = ois.readObject();
                        if(read instanceof Configuration) {
                            Configuration config = (Configuration) read;
                            ModuleLoader.getModuleLoader().log("Chargement de la configuration " + config.getId() + "...");
                            register(config);
                        } else {
                            Logger.getLogger("MyFreeTV").severe("Un objet du fichier de configuration n'est pas une configuration.");
                        }
                    } catch(EOFException oef) {
                        hasObject = false;
                    } catch(ObjectStreamException ose) {
                        Logger.getLogger("MyFreeTV").severe("Une configuration n'a pas pu être chargée (erreur d'I/O).");
                    } catch(ClassNotFoundException cnfe) {
                        Logger.getLogger("MyFreeTV").severe("Une configuration n'a pas pu être chargée (classe non trouvée).");
                    }
                } while(!hasObject);
     
            } catch(FileNotFoundException fnfe) {
                /* Le fichier n'existe pas... ce qui est normal lors du premier chargement du programme. */
            } catch(IOException ioe) {
                Logger.getLogger("MyFreeTV").severe("Erreur d'I/O dans le fichier de configuration.");
            } finally {
                try {
                    if(ois != null) {
                        ois.close();
                    } else if(fis != null) {
                        fis.close();
                    }
                } catch(IOException ioe) {}
            }
        }

  9. #9
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    Citation Envoyé par adiGuba
    Enfin, et parce que je suis très chiant : il y a un cas où tu ne fermes pas correctement le fichier !
    En effet comme le constructeur d'ObjectInputStream commence à lire le flux pour vérifier qu'il s'agit bien d'un fichier sérialisé, tu peux avoir une StreamCorruptedException...


    Donc dans le cas où le fichier ouvert n'est pas correct, la référence ois est null car le constructeur aura généré une exception, et tu n'appelles pas le close() (normal). Or tu as ouvert un FileInputStream qui ne sera pas fermé, et dont tu auras perdu la référence...
    Salut,

    En fait ça ne devrait pas poser de problème car ce n'est pas le constructeur qui retourne l'objet mais l'opérateur new. Cela signifie que même si le constructeur lève une exception avant que toutes ses instructions n'aient été exécutées, l'opérateur retournera quand même un objet, certes mal construit mais c'est suffisant pour que
    renvoie la valeur true.

    En revanche, il y a de fortes chances ensuite que
    lève une exception.

  10. #10
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par le y@m's
    Tu peux utiliser la méthode available() de ton ObjectInputStream.
    Ca ne marche pas, ça me renvoie 0, alors que si je fais la boucle while(true) il y a bien qqch à lire...

Discussions similaires

  1. Réponses: 5
    Dernier message: 13/07/2010, 14h04
  2. Pas d'événement OnClose quand on arrête W2K
    Par Altau dans le forum C++Builder
    Réponses: 9
    Dernier message: 26/01/2009, 18h36
  3. Détecter l'arrêt du système ?
    Par Jéremy A dans le forum API, COM et SDKs
    Réponses: 6
    Dernier message: 24/03/2003, 19h06
  4. [XMLRAD] test de nullité
    Par Pm dans le forum XMLRAD
    Réponses: 5
    Dernier message: 29/11/2002, 10h57
  5. test collisions
    Par tatakinawa dans le forum OpenGL
    Réponses: 5
    Dernier message: 08/06/2002, 06h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo