目录
第6章 编解码技术
![](https://img-blog.csdn.net/20180903112306121?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2wxMzk0MDQ5NjY0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
1 Java序列化的缺点
java序列化通过实现Serializable接口来实现
- 无法跨语言
- 序列化后的码流太大
- 序列化性能太低
java序列化的两个目的:网络传输和对象的持久化
对比的是java原生序列化和二进制序列化
java序列化方案:首先把对象信息写到ObjectOutputStream 中,然后再写到ByteArrayOutputStream 中,最后写到字节数组中;
二进制序列化方案:首先把name字段占用的大小写入,然后写入name的值,最后写入id;
用于测试序列化码流大小和序列化性能的对象
public class UserInfo implements Serializable {
/**
* 默认的序列号
*/
private static final long serialVersionUID = 1L;
private String userName;
private int userID;
public UserInfo buildUserName(String userName) {
this.userName = userName;
return this;
}
public UserInfo buildUserID(int userID) {
this.userID = userID;
return this;
}
/**
* @return the userName
*/
public final String getUserName() {
return userName;
}
/**
* @param userName
* the userName to set
*/
public final void setUserName(String userName) {
this.userName = userName;
}
/**
* @return the userID
*/
public final int getUserID() {
return userID;
}
/**
* @param userID
* the userID to set
*/
public final void setUserID(int userID) {
this.userID = userID;
}
public byte[] codeC() {
ByteBuffer buffer = ByteBuffer.allocate(1024);
byte[] value = this.userName.getBytes();
buffer.putInt(value.length);
buffer.put(value);
buffer.putInt(this.userID);
buffer.flip();
value = null;
byte[] result = new byte[buffer.remaining()];
buffer.get(result);
return result;
}
public byte[] codeC(ByteBuffer buffer) {
buffer.clear();
byte[] value = this.userName.getBytes();
buffer.putInt(value.length);
buffer.put(value);
buffer.putInt(this.userID);
buffer.flip();
value = null;
byte[] result = new byte[buffer.remaining()];
buffer.get(result);
return result;
}
}
测试码流大小:
public class TestUserInfo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
UserInfo info = new UserInfo();
info.buildUserID(100).buildUserName("Welcome to Netty");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bos);
os.writeObject(info);
os.flush();
os.close();
byte[] b = bos.toByteArray();
System.out.println("The jdk serializable length is : " + b.length);
bos.close();
System.out.println("-------------------------------------");
System.out.println("The byte array serializable length is : " + info.codeC().length);
}
}
输出:
The jdk serializable length is : 127
-------------------------------------
The byte array serializable length is : 24
测试序列化性能:
public class PerformTestUserInfo {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
UserInfo info = new UserInfo();
info.buildUserID(100).buildUserName("Welcome to Netty");
int loop = 1000000;
ByteArrayOutputStream bos = null;
ObjectOutputStream os = null;
long startTime = System.currentTimeMillis();
for (int i = 0; i < loop; i++) {
bos = new ByteArrayOutputStream();
os = new ObjectOutputStream(bos);
os.writeObject(info);
os.flush();
os.close();
byte[] b = bos.toByteArray();
bos.close();
}
long endTime = System.currentTimeMillis();
System.out.println("The jdk serializable cost time is : " + (endTime - startTime) + " ms");
System.out.println("-------------------------------------");
ByteBuffer buffer = ByteBuffer.allocate(1024);
startTime = System.currentTimeMillis();
for (int i = 0; i < loop; i++) {
byte[] b = info.codeC(buffer);
}
endTime = System.currentTimeMillis();
System.out.println("The byte array serializable cost time is : " + (endTime - startTime) + " ms");
}
}
输出:
The jdk serializable cost time is : 2029 ms
-------------------------------------
The byte array serializable cost time is : 135 ms