欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

序列化多个对象和反序列化遍历一个文件中的所有对象原理讲解

程序员文章站 2024-03-11 22:46:01
...

序列化多个对象和反序列化遍历一个文件中的所有对象原理讲解
  若不进行处理,直接继续序列化添加对象进去。会在追加时继续写个头部的四个字节
序列化多个对象和反序列化遍历一个文件中的所有对象原理讲解
直接读取时,报错!
序列化多个对象和反序列化遍历一个文件中的所有对象原理讲解
序列化多个对象和反序列化遍历一个文件中的所有对象原理讲解
下面和我们手动去掉;
序列化多个对象和反序列化遍历一个文件中的所有对象原理讲解
再次运行!
成功读取
序列化多个对象和反序列化遍历一个文件中的所有对象原理讲解

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;
    }



}

相关标签: 编程基础