一,超猪聊技术----jdk对象序列化协议
2015-02-05 15:25
127 查看
最近碰到一个项目,需要使用nodejs反序列化存储在redis中的session对象(jdk序列化),花了点时间研究了下jdk序列化协议。同时感谢fengmk2大神提供的开源项目java.io
1. 基本介绍
java中的对象序列化操作类可以ObjectOutputStream(写入), ObjectInputStream(读取),首先我们看看如何操作将对象序列化后写入文件和从文件中读取。
1.1 将str对象写入文件
string.bin写入结果如下, (可以使用editplus)
输出结果
00 05: 当前对象序列化格式的版本号
74: TC_STRING 表示string字符串的开始
03: 该string字符串的长度
73 74 72: 该string的值“str”
String对象的序列化还是比较简单的,接下来介绍复杂对象的序列化协议
3.1 Date对象序列化结构(写入文件方式和1.1一致, 此处就不再重复)
AC ED: 两个字节的"魔化数字"
00 05: 当前对象序列化格式的版本号
73: TC_OBJECT 表示对象开始
72: TC_CLASSDESC Class定义开始
00 0E: 类名(字符串)的长度
6A 61 76 61 2E 75 74 69 6C 2E 44 61 74 65: java.util.Date字符串(ASCII)
68 6A 81 01 4B 59 74 19: 8个字节的指纹
03: 1个字节长的标志(见附录介绍)
00 00: 2个字节长的数据或描述符的计数值
78: 结束标志
70: 没有超类
77: BlOCKDATA的开始标志
08: 数据字节长度
00 00 01 4B 6D 65 DB B4: 8个字节的time的值(1970年1月1日到该时间的毫秒数)
78: ENDBLOCKDATA 结束标志
标志位
SC_WRITE_METHOD: Class定义包含readObject, writeObject方法
标志为0x03, 判断是否包含SC_WRITE_METHOD
标志0x03, 转换为二进制
SC_WRITE_METHOD 0x01, 转换为二进制
终端符号和常量
![](http://7vzrp9.com1.z0.glb.clouddn.com/01.gif)
参考资料
jdk序列化介绍: https://docs.oracle.com/javase/7/docs/platform/serialization/spec/protocol.html1. 基本介绍
java中的对象序列化操作类可以ObjectOutputStream(写入), ObjectInputStream(读取),首先我们看看如何操作将对象序列化后写入文件和从文件中读取。 1.1 将str对象写入文件
String str = "str"; FileOutputStream fileOutputStream = new FileOutputStream("d://string.bin"); ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); objectOutputStream.writeObject(str);
string.bin写入结果如下, (可以使用editplus)
00000000 AC ED 00 05 74 00 03 73 74 72 ....t..str
1.2 从文件中读取str对象
FileInputStream fileInputStream = new FileInputStream("d://string.bin"); ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); Object str = objectInputStream.readObject(); System.out.println(str);
输出结果
str
2. Str对象协议解析
AC ED: 任何对象序列化后都是以这两个字节的"魔化数字"开始00 05: 当前对象序列化格式的版本号
74: TC_STRING 表示string字符串的开始
03: 该string字符串的长度
73 74 72: 该string的值“str”
String对象的序列化还是比较简单的,接下来介绍复杂对象的序列化协议
3. Date对象协议解析
3.1 Date对象序列化结构(写入文件方式和1.1一致, 此处就不再重复)
00000000 AC ED 00 05 73 72 00 0E 6A 61 76 61 2E 75 74 69 ....sr..java.uti 00000010 6C 2E 44 61 74 65 68 6A 81 01 4B 59 74 19 03 00 l.Datehj..KYt... 00000020 00 78 70 77 08 00 00 01 4B 6D 65 DB B4 78 .xpw....Kme..x
AC ED: 两个字节的"魔化数字"
00 05: 当前对象序列化格式的版本号
73: TC_OBJECT 表示对象开始
72: TC_CLASSDESC Class定义开始
00 0E: 类名(字符串)的长度
6A 61 76 61 2E 75 74 69 6C 2E 44 61 74 65: java.util.Date字符串(ASCII)
68 6A 81 01 4B 59 74 19: 8个字节的指纹
03: 1个字节长的标志(见附录介绍)
00 00: 2个字节长的数据或描述符的计数值
78: 结束标志
70: 没有超类
77: BlOCKDATA的开始标志
08: 数据字节长度
00 00 01 4B 6D 65 DB B4: 8个字节的time的值(1970年1月1日到该时间的毫秒数)
78: ENDBLOCKDATA 结束标志
3.2 Date对象的writeObject, readObjct方法
Date的类定义的标志显示包含SC_WRITE_METHOD(计算方式见附录), 表示类包含writeObject, readObject方法,数据读取写入都会依照该两个方法调用/** * Save the state of this object to a stream (i.e., serialize it). * * @serialData The value returned by <code>getTime()</code> * is emitted (long). This represents the offset from * January 1, 1970, 00:00:00 GMT in milliseconds. */ private void writeObject(ObjectOutputStream s) throws IOException { s.writeLong(getTimeImpl()); } /** * Reconstitute this object from a stream (i.e., deserialize it). */ private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { fastTime = s.readLong(); }
附录:
标志位
final static byte SC_WRITE_METHOD = 0x01; //if SC_SERIALIZABLE final static byte SC_BLOCK_DATA = 0x08; //if SC_EXTERNALIZABLE final static byte SC_SERIALIZABLE = 0x02; final static byte SC_EXTERNALIZABLE = 0x04; final static byte SC_ENUM = 0x10;
SC_WRITE_METHOD: Class定义包含readObject, writeObject方法
标志位计算方式
例:标志为0x03, 判断是否包含SC_WRITE_METHOD
标志0x03, 转换为二进制
0000 0011
SC_WRITE_METHOD 0x01, 转换为二进制
0000 0001做&运算结果如下
0000 0001该结果大于0, 则包含SC_WRITE_METHOD
终端符号和常量
final static short STREAM_MAGIC = (short)0xaced; final static short STREAM_VERSION = 5; final static byte TC_NULL = (byte)0x70; final static byte TC_REFERENCE = (byte)0x71; final static byte TC_CLASSDESC = (byte)0x72; final static byte TC_OBJECT = (byte)0x73; final static byte TC_STRING = (byte)0x74; final static byte TC_ARRAY = (byte)0x75; final static byte TC_CLASS = (byte)0x76; final static byte TC_BLOCKDATA = (byte)0x77; final static byte TC_ENDBLOCKDATA = (byte)0x78; final static byte TC_RESET = (byte)0x79; final static byte TC_BLOCKDATALONG = (byte)0x7A; final static byte TC_EXCEPTION = (byte)0x7B; final static byte TC_LONGSTRING = (byte) 0x7C; final static byte TC_PROXYCLASSDESC = (byte) 0x7D; final static byte TC_ENUM = (byte) 0x7E; final static int baseWireHandle = 0x7E0000;
![](http://7vzrp9.com1.z0.glb.clouddn.com/01.gif)
相关文章推荐
- 对象序列化与反序列化的常见技术
- java对象序列化技术
- .net中对象序列化技术浅谈(ZZ)
- .net中对象序列化技术浅谈
- 基于JAVA动态编译的高性能对象序列化技术
- Java 中对象的序列化技术
- 【Java核心技术】java对象的序列化与反序列化
- .net中对象序列化技术浅谈
- .net中对象序列化技术浅谈 (转)
- WPF架构关键技术剖析(2)--XAML、对象序列化、类动态实例化
- 一个利用了异步处理,事件驱动,对象序列化等技术的类Parser完整代码示例
- .net中对象序列化技术浅谈
- .net中对象序列化技术浅谈
- .net中对象序列化技术浅谈
- .net中对象序列化技术浅谈 转自周公的专栏
- Java 中对象的序列化技术(zz一篇java序列化的好文,强烈推荐)
- .net中对象序列化技术浅谈
- Java 中对象的序列化技术
- 使用Remoting 技术将对象序列化
- WPF架构关键技术剖析(2)--XAML、对象序列化、类动态实例化