2017-01-13 4 views
0

Pour mon application, je souhaite utiliser une carte pour agir en tant que base de données. Pour enregistrer et charger une carte, je vous écris/lecture à/de database.ser à l'aide des 2 méthodes:Solution de contournement java.io.EOFException cause par ObjectInputStream

private synchronized void saveDB() { 
    try { 
     fileOut = new FileOutputStream(db); 
     out = new ObjectOutputStream(fileOut); 
     out.writeObject(accounts); 
     fileOut.close(); 
     out.close(); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

} 

@SuppressWarnings("unchecked") 
private void loadDB() { 
    try { 
     fileIn = new FileInputStream(db); 
     in = new ObjectInputStream(fileIn); // that is where error is produced if fileIn is empty 
     accounts = (Map<String, Client>) in.readObject(); 
     in.close(); 
     fileIn.close(); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } catch (ClassNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

Je veux charger dans la carte lorsque l'application démarre, donc j'invoque la méthode dans le constructeur comme ceci:

protected DriveatorImpl() { 
    accounts = new ConcurrentHashMap<String, Client>(); 
    db = new File("C:/Users/eduar/git/Multy-Threaded-Bank-System/Bank-Services/database.ser"); 
// also, any suggestions how can I make path to a file more flexible in case I want to run Server side of an app on different machine? 
    if (!db.exists()) { 
     try { 
      db.createNewFile(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    loadDB(); // loads database when server start 
} 

Je suis conscient de ce qui provoque une erreur, mais je ne sais pas ce que je devrais changer ma conception pour éviter constructeur ObjectInputStream recevoir flux vide! Des suggestions sur ce que je peux faire différemment?

Modifier: Je souhaite noter que dans une nouvelle application, database.ser est vide car il n'y a pas encore d'entrées dans Map.

Merci!

Répondre

-1

D'abord pourquoi l'EOFExcpetion se produit?

  1. Il n'y a aucun contenu dans le fichier ou le fichier est vide et que vous avez essayé de lire le fichier.

    • Vous pouvez éviter l'exception EOFException pour un fichier vide en vérifiant la longueur du contenu du fichier si elle est inférieure ou égale à zéro si le fichier est vide. another way to check if file is empty

Certains changements de code et cela a fonctionné pour moi.

@SuppressWarnings("unchecked") 
private void loadDB() { 
    try { 
     if (db.length() <= 0) { 
      // if statement evaluates to true even if file doesn't exists 
      saveDB(); // save to a file an empty map 
         // if file doesn't exist, it creates a new one 
         // call loadDB inside constructor 

     } 
     FileInputStream fileIn = new FileInputStream(db); 
     ObjectInputStream in = new ObjectInputStream(fileIn); // that is where error is produced if fileIn is empty 
     in.readObject(); 
     in.close(); 
     fileIn.close(); 
     System.out.println(accounts); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } catch (ClassNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 
+0

Je ne peux pas faire la tête ou la queue de # 2, et le deuxième point de balle est également sans signification. Votre «autre façon» est exactement la même que votre façon originale de vérifier la vacuité. – EJP

+0

Je pense que vérifier pour le fichier vide et revenir de la méthode est exactement ce dont j'avais besoin! J'appelle saveDB() dans les méthodes où je mets ou modifie des valeurs dans la carte pour m'assurer que toutes les données sont sauvegardées au cas où le serveur tombe en panne. Je pense que je comprends maintenant pourquoi appeler la méthode saveDB() dans le constructeur avant que loadDB() ne fonctionne. Il écrit dans un fichier une carte vide, mais encore des octets qui traversent le flux. Le seul problème est que si certaines valeurs sont déjà stockées dans Map et que je les sauvegarde dans un fichier, l'instanciation suivante d'une classe remplacera le fichier par une carte vide et toutes les données seront perdues. Merci de votre aide! – GarRudo

+0

De rien. S'il vous plaît essayez d'éviter la question en double comme @EJP mentionné. Cela aidera à éviter les erreurs. Je vous remercie. –

0

Débarrassez-vous de la merde file.exists()/file.createNewFile(). Tout ce qu'il fait pour vous est de masquer le problème FileNotFoundException original, et de transformer en EOFException complètement prévisible en raison d'essayer de construire un ObjectInputStream autour d'un flux vide. Gérer le problème original. Ne bougez pas simplement, ou transformez-le en quelque chose d'autre.

+0

Je comprends maintenant quand vous lisez votre commentaire à l'article d'origine. Ce serait une solution gracieuse dont j'ai besoin. Je vous remercie. – GarRudo