若不進行處理,直接繼續序列化添加對象進去。會在追加時繼續寫個頭部的四個字節
直接讀取時,報錯!
下面和我們手動去掉;
再次運行!
成功讀取
package com.gqzdev;
import com.gqzdev.bean.User;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @ClassName: SeralizableTest
* @author: ganquanzhong
* @date: 2020/4/9 12:19
*/
public class SerializableTest implements Serializable {
public static void main(String[] args) throws IOException {
User user = new User(1001, "gqzdev-end"+new Date(), "女");
File file = new File("E:/ser");
/*
//序列化對象
serialize(user,file);
//反序列化
Object o =deserialize(file);
System.out.println(((User)o).toString());
*/
//序列化對象
//serializeAppend(user,file);
//反序列化
List<User> objList = deserializeObjList(file);
System.out.println(objList.size());
for (User user1:objList) {
System.out.println(user1.toString());
}
}
/**
* 序列化一個對象 , 並寫到文件中
*/
public static void serialize(Object o,File file) throws IOException {
ObjectOutputStream stream =new ObjectOutputStream(new FileOutputStream(file));
try {
stream.writeObject(o);
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 序列化多個對象!!!
* 使用ObjectOutputStream會調用writeStreamHeader();
* 自動帶上一個頭aced 0005(佔4個字節),然後每次讀取都讀完頭然後在讀內容。
* 導致追加數據時發生錯誤。解決方法就是先判斷文件是否存在。如果不存在,就先創建文件。追加的情況就是當判斷文件存在時,把那個4個字節的頭aced 0005截取掉,然後在把對象寫入到文件。這樣就實現了對象序列化的追加
*
*
* 但是呢在讀取的時候只有讀取一次StreamHeader的,所以導致出錯
*
* 解決方法,在序列化對象時,只保證寫一次 StreamHeader
*/
public static void serializeAppend(Object obj,File file) throws IOException {
//如果文件存在 就追加到後面 append
boolean isexist=false;
if (file.exists()){
isexist=true;
}
FileOutputStream fileOutputStream=new FileOutputStream(file,true);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
// 每次new的時候都會寫入一個StreamHeader,所以要把屁股後面的StreamHeader去掉
// 主要是處理fileOutputStream流的指針位置
// 可以說是文件的長度
long pos = 0;
if (isexist) {
// getChannel()返回此通道的文件位置,這是一個非負整數,它計算從文件的開始到當前位置之間的字節數
pos = fileOutputStream.getChannel().position() - 4;// StreamHeader有4個字節所以減去
// 將此通道的文件截取爲給定大小
fileOutputStream.getChannel().truncate(pos);
System.out.println("追加成功~");
}
objectOutputStream.writeObject(obj);
// 關閉流
objectOutputStream.close();
}
/**
* 從文件中,反序列化讀取到object中
*/
public static Object deserialize(File file) throws IOException{
ObjectInputStream stream = new ObjectInputStream(new FileInputStream(file));
try {
Object o = stream.readObject();
stream.close();
return o;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
public static List<User> deserializeObjList(File file) throws IOException{
List<User> list = new ArrayList<>();
FileInputStream fileInputStream = new FileInputStream(file);
ObjectInputStream stream = new ObjectInputStream(fileInputStream);
try {
//遍歷所有對象 available() > 0代表流中還有對象
while (fileInputStream.available()>0){
Object o = stream.readObject();
System.out.println(((User)o).toString());
list.add((User)o);
}
System.out.println("read-->"+list.size());
stream.close();
return list;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}