zoukankan      html  css  js  c++  java
  • 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();
                  }
              }
    	}
    }
    

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

    作者:鹏鹏
             
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如有问题请联系906522957@qq.com
  • 相关阅读:
    [iPad]PencilKit教程3、检查,修改和构造PencilKit绘图
    [iPad]PencilKit教程2、PencilKit的新功能
    [iPad]PencilKit教程1、PencilKit介绍
    为什么要谨慎使用Arrays.asList、ArrayList的subList?
    精通高并发与多线程,却不会用ThreadLocal?
    拥抱Kubernetes,再见了,SpringBoot @Scheduled
    从小公司进入大厂,我都做对了哪些事?
    总结我的Java朋友
    MySQL如何实时同步数据到ES?试试这款阿里开源的神器!
    基于Java访问数据库
  • 原文地址:https://www.cnblogs.com/liaoweipeng/p/4474680.html
Copyright © 2011-2022 走看看