Подтвердить что ты не робот

Как писать и читать java-сериализованные объекты в файл

Я собираюсь записать несколько объектов в файл, а затем восстановить их в другой части моего кода. У моего кода нет ошибок, но он работает неправильно. Не могли бы вы помочь мне найти, что не так в моем коде. Я читал разные коды с другого сайта, но никто из них не работал у меня!

Вот мой код для записи моих объектов в файл: MyClassList - это arraylist, который включает объекты моего класса (которые должны быть записаны в файл).

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));
}

Я добавил "true" к конструктору выходного потока, потому что я хочу добавить каждый объект в конец файла. Это правильно?

И вот мой код для чтения объектов из файла:

 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();
 }

Наконец, он печатает только один объект. Теперь я не знаю, правильно ли я пишу или правильно читаю!

4b9b3361

Ответ 1

Почему бы не сериализовать весь список сразу?

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

Предполагая, конечно, что MyClassList является ArrayList или LinkedList или другой коллекцией Serializable.

В случае чтения его обратно в вашем коде вы готовы только к одному элементу, нет петли для сбора всего написанного элемента.

Ответ 2

Как и предполагали другие, вы можете сериализовать и десериализовать весь список сразу, что проще и, кажется, полностью соответствует тому, что вы собираетесь делать.

В этом случае код сериализации становится

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();
    } 
}

И десериализация становится (предполагая, что myClassList является списком и надеясь, что вы будете использовать дженерики):

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();
    } 
}

Вы также можете десериализовать несколько объектов из файла, как вы намеревались:

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();
    } 
}

Пожалуйста, не забудьте закрыть потоковые объекты в предложении finally (обратите внимание: это может вызвать исключение).

РЕДАКТИРОВАТЬ

Как предлагается в комментариях, лучше использовать try с ресурсами, и код должен стать намного проще.

Вот список сериализации:

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

Ответ 3

Я думаю, что вам нужно написать каждый объект в собственный файл или вам нужно разбить его при чтении. Вы также можете попытаться сериализовать свой список и получить его при десериализации.

Ответ 4

если вы сериализуете весь список, вы также должны десериализовать файл в список, когда вы читаете его обратно. Это означает, что вы неизбежно загрузите в память большой файл. Это может быть дорого. Если у вас есть большой файл, и вам нужно разбить его на строки (-> объект за объектом), просто продолжайте свою первоначальную идею.

Сериализация:

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);
}

Десериализация:

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);
}

Ответ 5

Простая программа для записи объектов в файл и чтения объектов из файла.

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