参考: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();
}
}