Comment prévenir InputStream.readObject() de jeter EOFException?
Je sérialiser un objet et l'enregistrer comme un fichier sur mon disque dur. Quand je suis en train de lire ça, seulement dans certaines occasions, il jette EOFException. Après quelques heures de débogage je ne suis pas en mesure de trouver un problème.
Voici mon code:
public void serialize(MyClass myClass,String path) {
FileOutputStream foStream = null;
ObjectOutputStream ooStream = null;
try {
File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
foStream = new FileOutputStream(file);
ooStream = new ObjectOutputStream(foStream);
ooStream.writeObject(myClass);
} catch (Throwable t) {
log.error(t);
} finally {
if (ooStream != null) {
try {
ooStream.flush();
ooStream.close();
} catch (IOException e) {
log.error(e);
}
}
}
}
Pour obtenir de l'Objet:
public MyClass deSerialize(String path) {
MyClass myClass=null;
FileInputStream fiStream = null;
ObjectInputStream oiStream = null;
String errorMessage = "";
try {
File file = new File(path);
if (!file.exists()) {
return null;
}
fiStream = new FileInputStream(path);
oiStream = new ObjectInputStream(fiStream);
Object o = oiStream.readObject();
myClass = (MyClass) o;
} catch (Throwable t) {
log.warn(t);
} finally {
if (oiStream != null) {
try {
oiStream.close();
} catch (IOException e) {
log.error(e);
}
}
}
return myClass;
}
Stacktrace:
java.io.EOFException à
java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2498)
à java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1273)
à java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
à java.util.LinkedList.readObject(LinkedList.java:776) à
soleil.de réfléchir.GeneratedMethodAccessor583.invoke(Source Inconnue) à
soleil.de réfléchir.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
à java.lang.de réfléchir.La méthode.invoke(la Méthode.java:585) à
java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:946)
au
java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1809)
au
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719)
à java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
au
java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1908)
au
java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1832)
au
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719)
à java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
à java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
Question:
Mon objet sérialisé est maintenant corrompu et puis c'est de la foutaise maintenant?
Parce que cet objet est responsable pour le rendu de l'INTERFACE utilisateur enregistrées par l'utilisateur. Si l'Utilisateur se connecte, il doit rendre précédemment sauvé de l'état de l'INTERFACE utilisateur. Cependant, pour certains utilisateurs, le fichier ne peut pas être désérialisé.
- Stacktrace s'il vous plaît?
- Le point de code qui ferme la
FileOutputStream
est inutile; la fermeture de laObjectOutputStream
aussi ferme le fichier. - J'ai ajouté stacktrace
- Par hasard, est
oiStream.readObject()
appelé très peu de temps aprèsooStream.writeObject()
? Je suis en supposant que le disque dur est encore dans le processus d'écriture de ce fichier sur le disque et readObject() tente de le lire. Pour confirmer mis délibérémentThread.Sleep(5000);
juste avant lareadObject()
appel. - Camion, je ne pense pas, il y a assez de temps entre la lecture et l'écriture...
- Essayez de diviser le problème en écriture ou en lecture. Envelopper le lire dans une fonction qui attrape EOFException et les tentatives de le lire une fois de plus. Si elle échoue de manière fiable sur le réessayer, vous connaissez le problème, c'est écrit.
- J'ai essayé comme vous l'a dit en attrapant
EOFException
mais il continue de manière récursive infinie... - Bon. Le problème est donc de l'écriture. Avez-vous un moyen de les arrêter une fois que vous le détecter? Alors peut-être vous pouvez comparer le contenu du fichier avec une bonne.
Vous devez vous connecter pour publier un commentaire.
EOFException
signifie que vous essayez de lire au-delà de la fin du fichier. Normalement, vous n'avez pas de moyen de savoir whethere il y a plus d'objets à lire, d'autres que de l'essayer, donc vous ne devriez pasEOFException
comme un problème en premier lieu. Si elle est jetée dans une situation où vous pensez que vous savoir il y a plus d'objets dans le fichier, par exemple lorsque vous avez préfixé un nombre d'objets dans le fichier, il indique un problème avec le code qui a écrit le fichier, ou la possible corruption du fichier lui-même. Un autre exemple est d'une longueur de zéro fichier qui ne doit pas être de longueur zéro. Quel que soit le problème, il ne peut pas être résolu par la lecture de la fin, il est déjà trop tard.Je ne vois aucun problème avec l'écriture et de la lecture du fichier.
Donc ma meilleure supposition est que le problème est au niveau du fichier. Par exemple:
Je vous suggère d'ajouter un peu de traçage code qui utilise le Fichier.longueur() pour savoir ce que la taille du fichier est après que vous avez écrit et avant de la lire.
Un couple de d'autres possibilités:
l'écrivain et le lecteur de code à l'aide de différentes versions de
MyClass
(ou une classe dépendante) incompatible avec les représentations et les mêmes serialVersionId valeurs, ouvous pourriez être en utilisant des
readObject
etwriteObject
méthodes qui sont incompatibles.Dans mon cas, EOF Exception a été résolu en s'assurant de la lecture et l'écrit dans le fichier ont été thread-safe. Comme Stephen C a répondu ci-dessus, si vous essayez d'écrire dans un fichier dont vous êtes aussi essayez de lire à partir de dire à partir d'un autre thread, vous pouvez marcher sur le ObjectInputStream qui va se jeter EOF Exception dans ce cas.