web-dev-qa-db-fra.com

Comment écrire et lire des objets sérialisés Java dans un fichier

Je vais écrire plusieurs objets dans un fichier, puis les récupérer dans une autre partie de mon code. Mon code n'a pas d'erreur, mais il ne fonctionne pas correctement. Pourriez-vous s'il vous plaît m'aider à trouver ce qui ne va pas avec mon code ... J'ai lu des codes différents d'un site Web à l'autre, mais aucun d'entre eux n'a fonctionné pour moi!

Voici mon code pour écrire mes objets dans un fichier: MyClassList est un arraylist qui inclut des objets de ma classe (qui doivent être écrits dans un fichier).

for (int cnt = 0; cnt < MyClassList.size(); cnt++) {
    FileOutputStream fout = new FileOutputStream("G:\\address.ser", true);
    ObjectOutputStream oos = new ObjectOutputStream(fout);
    oos.writeObject(MyClassList.get(cnt));
}

J'ai ajouté "true" au constructeur du flux de sortie, parce que je veux ajouter chaque objet à la fin du fichier. Est-ce exact?

Et voici mon code pour lire les objets du fichier:

 try {
     streamIn = new FileInputStream("G:\\address.ser");
     ObjectInputStream objectinputstream = new ObjectInputStream(streamIn);
     MyClass readCase = (MyClass) objectinputstream.readObject();
     recordList.add(readCase);
     System.out.println(recordList.get(i));
 } catch (Exception e) {
     e.printStackTrace();
 }

Il n'imprime finalement qu'un seul objet. Maintenant, je ne sais pas si je n'écris pas correctement ou si je ne lis pas correctement!

48
user1419243

Pourquoi ne pas sérialiser la liste entière à la fois?

FileOutputStream fout = new FileOutputStream("G:\\address.ser");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(MyClassList);

En supposant, bien entendu, que MyClassList est une collection ArrayList ou LinkedList ou une autre collection Serializable.

Dans le cas de le relire, dans votre code, vous ne préparez qu'un seul élément, il n'y a pas de boucle pour rassembler tous les éléments écrits.

66
forty-two

Comme d'autres l'ont suggéré, vous pouvez sérialiser et désérialiser la liste entière en une fois, ce qui est plus simple et semble parfaitement correspondre à ce que vous souhaitez faire.

Dans ce cas, le code de sérialisation devient

ObjectOutputStream oos = null;
FileOutputStream fout = null;
try{
    fout = new FileOutputStream("G:\\address.ser", true);
    oos = new ObjectOutputStream(fout);
    oos.writeObject(myClassList);
} catch (Exception ex) {
    ex.printStackTrace();
} finally {
    if(oos != null){
        oos.close();
    } 
}

Et la désérialisation devient (en supposant que myClassList est une liste et en espérant que vous utiliserez des génériques):

ObjectInputStream objectinputstream = null;
try {
    FileInputStream streamIn = new FileInputStream("G:\\address.ser");
    objectinputstream = new ObjectInputStream(streamIn);
    List<MyClass> readCase = (List<MyClass>) objectinputstream.readObject();
    recordList.add(readCase);
    System.out.println(recordList.get(i));
} catch (Exception e) {
    e.printStackTrace();
} finally {
    if(objectinputstream != null){
        objectinputstream .close();
    } 
}

Vous pouvez également désérialiser plusieurs objets d'un fichier, comme vous le souhaitez:

ObjectInputStream objectinputstream = null;
try {
    streamIn = new FileInputStream("G:\\address.ser");
    objectinputstream = new ObjectInputStream(streamIn);
    MyClass readCase = null;
    do {
        readCase = (MyClass) objectinputstream.readObject();
        if(readCase != null){
            recordList.add(readCase);
        } 
    } while (readCase != null)        
    System.out.println(recordList.get(i));
} catch (Exception e) {
    e.printStackTrace();
} finally {
    if(objectinputstream != null){
        objectinputstream .close();
    } 
}

N'oubliez pas de fermer les objets de flux dans une clause finally (remarque: elle peut lever une exception).

MODIFIER

Comme suggéré dans les commentaires, il devrait être préférable d'utiliser essayer avec des ressources et le code devrait devenir assez simple. 

Voici la liste de sérialisation:

try(
    FileOutputStream fout = new FileOutputStream("G:\\address.ser", true);
    ObjectOutputStream oos = new ObjectOutputStream(fout);
){
    oos.writeObject(myClassList);
} catch (Exception ex) {
    ex.printStackTrace();
}
44
C.Champagne

Programme simple pour écrire des objets dans un fichier et lire des objets à partir d'un fichier.

package program;

import Java.io.File;
import Java.io.FileInputStream;
import Java.io.FileOutputStream;
import Java.io.ObjectInputStream;
import Java.io.ObjectOutputStream;
import Java.io.Serializable;

public class TempList {

  public static void main(String[] args) throws Exception {
    Counter counter = new Counter(10);

    File f = new File("MyFile.txt");
    FileOutputStream fos = new FileOutputStream(f);
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(counter);
    oos.close();

    FileInputStream fis = new FileInputStream(f);
    ObjectInputStream ois = new ObjectInputStream(fis);
    Counter newCounter = (Counter) ois.readObject();
    System.out.println(newCounter.count);
    ois.close();
  }

}

class Counter implements Serializable {

  private static final long serialVersionUID = -628789568975888036 L;

  int count;

  Counter(int count) {
    this.count = count;
  }
}

Après avoir exécuté le programme, la sortie de la fenêtre de la console sera 10 et vous pourrez trouver le fichier dans le dossier Test en cliquant sur l’icône affichée dans l’image ci-dessous.

 enter image description here

1
Roshan Halwai

si vous sérialisez toute la liste, vous devez également désérialiser le fichier dans une liste lorsque vous le relisez. Cela signifie que vous allez inévitablement charger en mémoire un gros fichier. Cela peut coûter cher Si vous avez un gros fichier et que vous avez besoin de le découper ligne par ligne (-> objet par objet), continuez avec votre idée initiale.

Sérialisation:

LinkedList<YourObject> listOfObjects = <something>;
try {
    FileOutputStream file = new FileOutputStream(<filePath>);
    ObjectOutputStream writer = new ObjectOutputStream(file);
    for (YourObject obj : listOfObjects) {
        writer.writeObject(obj);
    }
    writer.close();
    file.close();
} catch (Exception ex) {
    System.err.println("failed to write " + filePath + ", "+ ex);
}

Désérialisation:

try {
    FileInputStream file = new FileInputStream(<filePath>);
    ObjectInputStream reader = new ObjectInputStream(file);
    while (true) {
        try { 
            YourObject obj = (YourObject)reader.readObject();
            System.out.println(obj)
        } catch (Exception ex) {
            System.err.println("end of reader file ");
            break;
        }
    }
} catch (Exception ex) {
    System.err.println("failed to read " + filePath + ", "+ ex);
}
0
angelo.mastro

Je pense que vous devez écrire chaque objet dans un fichier ou scinder celui-ci à la lecture .. Vous pouvez également essayer de sérialiser votre liste et de la récupérer lors de la désérialisation. 

0
Sammy