如何将java序列化对象写入和读取到文件中

use*_*243 52 java serialization file

我将把多个对象写入一个文件,然后在我的代码的另一部分中检索它们.我的代码没有错误,但它无法正常工作.你能帮我找一下我的代码有什么问题吗?我从不同的网站上读过不同的代码,但没有一个能为我工作!

这是我将对象写入文件的代码: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));
}
Run Code Online (Sandbox Code Playgroud)

我将"true"添加到outputstream的构造函数中,因为我想将每个对象添加到文件末尾.那是对的吗?

这是我的代码从文件中读取对象:

 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();
 }
Run Code Online (Sandbox Code Playgroud)

它最终只打印一个对象.现在,我不知道我是不是写得不好还是读得不对!

for*_*two 70

为什么不一次序列化整个列表?

FileOutputStream fout = new FileOutputStream("G:\\address.ser");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(MyClassList);
Run Code Online (Sandbox Code Playgroud)

假设,当然,这MyClassList是ArrayListLinkedList,或其他Serializable集合.

在阅读它的情况下,在你的代码中你只准备了一个项目,没有循环来收集所有写的项目.

  • 别忘了关闭fout和oos !! [fout.close(); oos.close();] (10认同)
  • 通过在`FileOutputStream`和`ObjectOutputStream`之间使用`BufferedOutputStream`,可以大大提高性能. (3认同)
  • 问题是关于阅读和写作,但这个答案只涵盖写作。 (2认同)

C.C*_*gne 45

正如其他人建议的那样,您可以一次序列化和反序列化整个列表,这更简单,似乎完全符合您的意图.

在那种情况下,序列化代码变为

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();
    } 
}
Run Code Online (Sandbox Code Playgroud)

并且反序列化变为(假设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();
    } 
}
Run Code Online (Sandbox Code Playgroud)

您也可以按照以下方式从文件中反序列化多个对象:

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();
    } 
}
Run Code Online (Sandbox Code Playgroud)

请不要忘记在finally子句中关闭流对象(注意:它可以抛出异常).

编辑

正如评论中所建议的那样,最好使用try with resources,代码应该变得更加简单.

这是列表序列化:

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

  • 自从您实现了try/catch以来,应该是已接受的答案 (5认同)
  • 如果您使用Java 8,则可以使用try with resources (3认同)