今日份程式碼,解決 ObjectOutputStream 多次寫入發生重複寫入相同資料的問題
核心區別如下:
package com.sxd.swapping.objoutputstream; import org.junit.Test; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; /** * ObjectOutputStream 寫物件到序列化檔案中 * ObjectInputStream 讀物件到反序列化檔案中 */ public class SerializeTest { /** * 寫生成序列化檔案 * * 對同一個 共享物件 做重複性的多次寫入 建議使用writeObject + reset方法 組合使用 做重置動作 (即深克隆效果)下面這個 方法寫入的 是 test1 test2 test3 三條。 * 對於 非共享物件, 做多次重複性的寫入 可以使用 writeUnshared 方法(即淺克隆效果) * * * * 而 單獨使用 writeObject方法,會導致 第二次寫入的物件 依舊是 第一次寫對的物件。即 流不對被重置,導致下面這個 方法寫入的 是錯誤的 test1 test2 test1 test2 四條。 * * @throws Exception */ @Test public void test3() throws Exception { List<Student> students = new ArrayList<>(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(new File("C:/Users/ouiyuio/Desktop/students.ser"))); for (int i = 1; i <= 3; i++) { Student student = new Student(i, "test" + i); students.add(student); if (students.size() >= 2) { // objectOutputStream.writeUnshared(students); objectOutputStream.writeObject(students); objectOutputStream.reset(); //使用 reset保證寫入重複物件時進行了重置操作 students.clear(); } } if (students.size() > 0) { objectOutputStream.writeObject(students); objectOutputStream.flush(); } objectOutputStream.writeObject(null); objectOutputStream.close(); } /** * 反序列化讀取檔案內容 * @throws Exception */ @Test public void test4() throws Exception { ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(new File("C:/Users/ouiyuio/Desktop/students.ser"))); List<Student> students = (List<Student>) objectInputStream.readObject(); int count = 0; while (students != null) { count += students.size(); for (Student student : students) { System.out.println(student); } students = (List<Student>) objectInputStream.readObject(); } objectInputStream.close(); System.out.println(count); } @Test public void test5() throws Exception { int count = 0; ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(new File("C:/Users/ouiyuio/Desktop/students.ser"))); List<Student> students1 = (List<Student>) objectInputStream.readObject(); count += students1.size(); for (Student student : students1) { System.out.println(student); } List<Student> students2 = (List<Student>) objectInputStream.readObject(); count += students2.size(); for (Student student : students2) { System.out.println(student); } objectInputStream.close(); System.out.println(count); } }