這幾天做一個小的聊天項目用到對象序列化的知識,發現對象序列化不能像普通文件一樣直接追加對象。每次寫入對象都會被覆蓋。弄了2個多小時終於解決了。Java默認的對象序列化是每次寫入對象都會寫入一點頭aced 0005(占4個字節),然后每次讀取都讀完頭然后在讀內容。解決方法就是先判斷文件是否存在。如果不存在,就先創建文件。然后寫了第一個對象,也寫入了頭aced 0005。追加的情況就是當判斷文件存在時,把那個4個字節的頭aced 0005截取掉,然后在把對象寫入到文件。這樣就實現了對象序列化的追加。代碼如下:
首先我們要寫一個對類,用於對象的序列化,這個類實現了Serializable接口。類的定義如下:

package qq.client.tools; import java.io.*; /** * 這是對象序列化的程序 * 實現了對象序列化的追加 * @author Administrator * */ public class ObjectOutputTest { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub Message m = new Message(); m.setName("aaaaaaaaaaaaaaaaaaaaa"); File file=new File("D:\\jjm.txt"); boolean isexist=false;//定義一個用來判斷文件是否需要截掉頭aced 0005的 if(file.exists()){ //文件是否存在 isexist=true; FileOutputStream fo=new FileOutputStream(file,true); ObjectOutputStream oos = new ObjectOutputStream(fo); long pos=0; if(isexist){ pos=fo.getChannel().position()-4;//追加的時候去掉頭部aced 0005 fo.getChannel().truncate(pos); } oos.writeObject(m);//進行序列化 System.out.println("追加成功"); }else{//文件不存在 file.createNewFile(); FileOutputStream fo=new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fo); oos.writeObject(m);//進行序列化 oos.close(); System.out.println("首次對象序列化成功!"); } } }
下面是反系列化的實現。注意要在循環外面關閉流,在里面關閉會出現句柄無效的錯誤。
package qq.client.tools;
import java.io.*;
public class ObjectInputTest {
/**這是反序列化的程序
* 實現從文件讀取多個對象
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
File file = new File("D:"+File.separator+"jjm.txt");
if(file.exists()){
ObjectInputStream ois;
try {
FileInputStream fn=new FileInputStream(file);
ois = new ObjectInputStream(fn);
while(fn.available()>0){//代表文件還有內容
Message p = (Message)ois.readObject();//從流中讀取對象
System.out.println(p.getName());
}
ois.close();//注意在循環外面關閉
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
整個序列化對象的追加與從文件讀取多個對象實就實現了。
