java 高效序列化 Externalizable接口

参考:https://www.javacodegeeks.com/2010/07/java-best-practices-high-performance.html

首先需要序列化的类实现Externalizable接口

实现readExternal和writeExternal方法写文件的顺序和读取文件的顺序进行一一对应

需要注意的地方:被序列化的对象需要有一个无参的构造函数。

例子:

被序列化的类:
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

public class Employee implements Externalizable {
     private String firstName;
      private String lastName;
      private String socialSecurityNumber;
      private String department;
      private String position;
      private Date hireDate;
      private Double salary;
      private Employee supervisor;
      private List<String> phoneNumbers;
      public Employee() {
      }

      public Employee(String firstName, String lastName,
        String socialSecurityNumber, String department, String position,
        Date hireDate, Double salary) {
       this.firstName = firstName;
       this.lastName = lastName;
       this.socialSecurityNumber = socialSecurityNumber;
       this.department = department;
       this.position = position;
       this.hireDate = hireDate;
       this.salary = salary;
      }

      public String getFirstName() {
       return firstName;
      }

      public void setFirstName(String firstName) {
       this.firstName = firstName;
      }

      public String getLastName() {
       return lastName;
      }

      public void setLastName(String lastName) {
       this.lastName = lastName;
      }

      public String getSocialSecurityNumber() {
       return socialSecurityNumber;
      }

      public void setSocialSecurityNumber(String socialSecurityNumber) {
       this.socialSecurityNumber = socialSecurityNumber;
      }

      public String getDepartment() {
       return department;
      }

      public void setDepartment(String department) {
       this.department = department;
      }

      public String getPosition() {
       return position;
      }

      public void setPosition(String position) {
       this.position = position;
      }

      public Date getHireDate() {
       return hireDate;
      }

      public void setHireDate(Date hireDate) {
       this.hireDate = hireDate;
      }

      public Double getSalary() {
       return salary;
      }

      public void setSalary(Double salary) {
       this.salary = salary;
      }

      public Employee getSupervisor() {
       return supervisor;
      }

      public void setSupervisor(Employee supervisor) {
       this.supervisor = supervisor;
      }

      public List<String> getPhoneNumbers() {
       return phoneNumbers;
      }

      public void setPhoneNumbers(List<String> phoneNumbers) {
       this.phoneNumbers = phoneNumbers;
      }

      public void readExternal(ObjectInput objectInput) throws IOException,
        ClassNotFoundException {

       this.firstName = objectInput.readUTF();
       this.lastName = objectInput.readUTF();
       this.socialSecurityNumber = objectInput.readUTF();
       this.department = objectInput.readUTF();
       this.position = objectInput.readUTF();
       this.hireDate = new Date(objectInput.readLong());
       this.salary = objectInput.readDouble();

       int attributeCount = objectInput.read();

       byte[] attributes = new byte[attributeCount];

       objectInput.readFully(attributes);

       for (int i = 0; i < attributeCount; i++) {
        byte attribute = attributes[i];

        switch (attribute) {
        case (byte) 0:
         this.supervisor = (Employee) objectInput.readObject();
         break;
        case (byte) 1:
         this.phoneNumbers = Arrays.asList(objectInput.readUTF().split(";"));
         break;
        }
       }

      }

      public void writeExternal(ObjectOutput objectOutput) throws IOException {

       objectOutput.writeUTF(firstName);
       objectOutput.writeUTF(lastName);
       objectOutput.writeUTF(socialSecurityNumber);
       objectOutput.writeUTF(department);
       objectOutput.writeUTF(position);
       objectOutput.writeLong(hireDate.getTime());
       objectOutput.writeDouble(salary);

       byte[] attributeFlags = new byte[2];

       int attributeCount = 0;

       if (supervisor != null) {
        attributeFlags[0] = (byte) 1;
        attributeCount++;
       }
       if (phoneNumbers != null && !phoneNumbers.isEmpty()) {
        attributeFlags[1] = (byte) 1;
        attributeCount++;
       }

       objectOutput.write(attributeCount);

       byte[] attributes = new byte[attributeCount];

       int j = attributeCount;

       for (int i = 0; i < 2; i++)
        if (attributeFlags[i] == (byte) 1) {
         j--;
         attributes[j] = (byte) i;
        }

       objectOutput.write(attributes);

       for (int i = 0; i < attributeCount; i++) {
        byte attribute = attributes[i];

        switch (attribute) {
        case (byte) 0:
         objectOutput.writeObject(supervisor);
         break;
        case (byte) 1:
         StringBuilder rowPhoneNumbers = new StringBuilder();
         for(int k = 0; k < phoneNumbers.size(); k++)
          rowPhoneNumbers.append(phoneNumbers.get(k) + ";");
         rowPhoneNumbers.deleteCharAt(rowPhoneNumbers.lastIndexOf(";"));
         objectOutput.writeUTF(rowPhoneNumbers.toString());
         break;
        }
       }

      }

    @Override
    public String toString() {
        return "Employee [firstName=" + firstName + ", lastName=" + lastName
                + ", socialSecurityNumber=" + socialSecurityNumber
                + ", department=" + department + ", position=" + position
                + ", hireDate=" + hireDate + ", salary=" + salary
                + ", supervisor=" + supervisor + ", phoneNumbers="
                + phoneNumbers + "]";
    }

}
序列化方法类
public class Seilize {
    public static byte[] serializeObject(Externalizable object, int index)throws Exception {
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        byte[] res = null;
        try {
            fos = new FileOutputStream(new File(index + ".ser"));
            oos = new ObjectOutputStream(fos);
            object.writeExternal(oos);
            oos.flush();
            res = object.getClass().getName().getBytes();
        } catch (Exception ex) {
            throw ex;
        } finally {
            try {
                if (oos != null)
                    oos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return res;
    }

    public static Externalizable deserializeObject(byte[] rowObject, int index)throws Exception {
        FileInputStream fis = null;
        ObjectInputStream ois = null;
        String objectClassName = null;
        Externalizable res = null;
        try {
            fis = new FileInputStream(new File(index + ".ser"));
            objectClassName = new String(rowObject);
            ois = new ObjectInputStream(fis);
            Class objectClass = Class.forName(objectClassName);
            res = (Externalizable) objectClass.newInstance();
            res.readExternal(ois);
        } catch (Exception ex) {
            throw ex;
        } finally {
            try {
                if (ois != null)
                    ois.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return res;
    }
}
测试类
public static void main(String[] args) {
        Employee employee = new Employee("ni","hao","ha","helllo","world",new Date(),100.0); 
        try {
            byte[] rowObject = Seilize.serializeObject(employee,1);
            System.out.println(rowObject);
            System.out.println(Seilize.deserializeObject(rowObject,1));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值