基于Java提供的对象输入/输出ObjectInputStream和ObjectOutputStream,可以直接把Java对象作为可存储的字节数组写入文件,也可以传输到网络上,对于程序员来说,基于JDK默认的序列化机制可以避免操作底层字节数组,从而提升开发效率。
当进行进程跨进程的调用时,需要把被传输的Java对象编码为字节数组或者ByteBuffer对象,而当远程服务收到字节数组或者ByteBuffer时,需要将其解码为Java对象。这被称为Java对象编解码技术。
package com.phei.netty;
import java.io.Serializable;
public class UserInfo implements Serializable {
private static final long serialVersionUID = -5867548109897989552L;
private String userName;
private int userID;
public UserInfo(String userName,int userID){
this.userName = userName;
this.userID = userID;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getUserID() {
return userID;
}
public void setUserID(int userID) {
this.userID = userID;
}
}
package com.phei.netty;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
public class UserInfoTest {
public static void main(String args[]) throws IOException{
UserInfo user = new UserInfo("Hello World", 666666);
System.out.println("/*-------------------序列号字节流长度对比--------------------------*/");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(user);
oos.flush();
oos.close();
byte [] b = bos.toByteArray();
System.out.println("Java jdk自带的序列化字节流的大小"+b.length);
bos.close();
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put(user.getUserName().getBytes());
buffer.putInt(user.getUserID());
buffer.flip();
byte [] result = new byte[buffer.remaining()];
buffer.get(result);
System.out.println("ByteBuffer的二进制压缩后字节流的大小"+result.length);
System.out.println();
System.out.println("/*-------------------序列号性能对比--------------------------*/");
long startTimeMillis = System.currentTimeMillis();
for(int i=0;i<1000;i++){
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bos);
oos.writeObject(user);
oos.flush();
oos.close();
byte [] bb = bos.toByteArray();
bos.close();
}
System.out.println("Java 自带序列化花费时间:"+(System.currentTimeMillis()-startTimeMillis));
long startTimeMil = System.currentTimeMillis();
for(int i=0;i<1000;i++){
ByteBuffer buf = ByteBuffer.allocate(1024);
buf.put(user.getUserName().getBytes());
buf.putInt(user.getUserID());
buf.flip();
byte [] res = new byte[buf.remaining()];
buf.get(res);
}
System.out.println("ByteBuffer的序列化花费时间:"+(System.currentTimeMillis()-startTimeMil));
}
}
package com.leehongee.netserver.net.bean;
option java_package = "com.phei.netty.protobuf";
option java_outer_classname = "UserInfo";
message User{
required int32 userID = 1;
required string userName = 2;
}
package com.phei.netty.protobuf;
import java.io.IOException;
import com.google.protobuf.InvalidProtocolBufferException;
public class UserInfoTest {
private static byte[] encode(UserInfo.User user){
return user.toByteArray();
}
/**
* 反序列化
* @param body
* @return
* @throws InvalidProtocolBufferException
*/
private static UserInfo.User decode(byte[] body) throws InvalidProtocolBufferException{
return UserInfo.User.parseFrom(body);
}
/**
* 序列化
* @return
*/
private static UserInfo.User createUser(){
UserInfo.User.Builder builder = UserInfo.User.newBuilder();
builder.setUserID(666666);
builder.setUserName("hello world");
return builder.build();
}
public static void main(String[] args) throws IOException {
UserInfo.User user = createUser();
System.out.println("protobuf序列化后字节流大小"+user.toByteArray().length);
System.out.println("Before encode : "+ user.toString());
System.out.println(encode(user).length);
UserInfo.User user2 = decode(encode(user));
System.out.println("After decode : "+ user.toString());
}
}
UserInfo类
package com.phei.netty.messagepack; import org.msgpack.annotation.Message; @Message public class UserInfo{ public String userName; public int userID; }
UserInfoTest类
package com.phei.netty.messagepack;
import java.io.IOException;
import org.msgpack.MessagePack;
public class UserInfoTest {
public static void main(String args[]) throws IOException{
UserInfo user = new UserInfo();
user.userID=666666;
user.userName="hello world";
MessagePack pack = new MessagePack();
//序列化
byte[] bytes = pack.write(user);
System.out.println("MessagePack序列化后字节流大小:"+bytes.length);
//反序列化
UserInfo u = pack.read(bytes, UserInfo.class);
System.out.println("DeviceID: "+u.userName);
}
}