Как писать и читать 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();
}
Наконец, он печатает только один объект. Теперь я не знаю, правильно ли я пишу или правильно читаю!
Ответы
Ответ 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;
}
}