基于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; } }
<pre name="code" class="java">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类
</pre><pre name="code" class="java">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); } }