Fork me on GitHub

Java对象序列化文件追加对象的问题,以及Java的读取多个对象的问题解决方法。

       这几天做一个小的聊天项目用到对象序列化的知识,发现对象序列化不能像普通文件一样直接追加对象。每次写入对象都会被覆盖。弄了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();
              }
          }
	}
}

  整个序列化对象的追加与从文件读取多个对象实就实现了。

posted @ 2015-05-03 23:25  鹏&鹏  阅读(9212)  评论(4编辑  收藏  举报