RPC的世界,由于涉及到进程间网络远程通信,不可避免的需要将信息序列化后在网络间传送,序列化有两大流派: 文本和二进制.

文本序列化

序列化的实现有很多方式,在异构系统中最常用的就是定义成人类可读的文本形式,其在开发时debug比较方便.

常见的有:

  • 如通过http协议传送并用soap协议(实际形式为xml)封装的webservice方式.
  • http传送,封装形式为json.

二进制序列化

二进制序列化会比较复杂,由于字节流只是一组101010,需要一个比较详细的协议来定义被序列化后的二进制流的每个字节的含义是什么.一般使用其原因是其在网络传送效率较高,但牺牲了可读性.

常见的有:

  • Protocol Buffers
  • Thrift
  • Java序列化

重点介绍下java序列化. JDK1.1起,sun就有Java Object Serialization Specification定义java的序列化方式,根据文档,可以根据字节流读出序列化后的含义. 地址在这里.

借用一张java rmi的图解释一下其工作方式:

客户端与服务端都需要有实现了rmi接口的实现类,该接口在实际远程通信的时候作为一个桩类来处理网络通信的各种细节.而其传递的信息,就是java对象序列化后的二进制流.

读懂java序列化流

我们给一个简单的例子,定义一个简单实现了serializable接口的类:

class Pet implements Serializable{
private static final long serialVersionUID = 2L;
int paws;
}

再写一段将Pet序列化到文件中的程序:

public class Main {

    public static void main(String[] args) {
System.out.println("Hello World!");
Pet dto = new Pet();
File file = new File("/users/kunrong/p3.txt");
try {
ObjectOutputStream oout =
new ObjectOutputStream(new FileOutputStream(file));
oout.writeObject(dto);
} catch (IOException e) {
e.printStackTrace();
}
}
}

什么也没干,直接将其内容输出到p3.txt文件中.运行后,由于序列化后写出的是二进制流,所以用能打开二进制文件的编辑器打开,在mac下我用的是HexMiner,免费.

这些是什么意思呢?先摘取部分协议文档定义的常量内容:

final static short STREAM_MAGIC = (short)0xaced;

final static short STREAM_VERSION = 5;

final static byte TC_CLASSDESC = (byte)0x72;

final static byte TC_OBJECT = (byte)0x73;

下面对照图中每个16进制

  • 0xACED:根据协议文档的约定,由于所有二进制流(文件)都需要在流的头部约定魔数(magic number=STREAM_MAGIC),既java object 序列化后的流的魔数约定为ACED;

  • 0x0005:然后是流协议版本是short类型(2字节)并且值为5,则十六进制值为0005;

  • 0x7372:java byte型长度为1字节,所以0x73 0x72直接对应到字节流上,0x73(TC_OBJECT)代表这是一个对象,0x72(TC_CLASSDESC)代表这个之后开始是对类的描述.

  • 0x0003:类名的长度,这个类名是Pet,是三个字符,所以长度是3,对应16进制中就是0x0003.

  • 0x506574:这三个字节转为ASCII码就是类名Pet.

  • 0x00 00 00 00 00 00 00 02: 由于序列化中标识类版本是这样定义的

private static final long serialVersionUID = 2L;

是long型,long在java中的定义是8字节,所以这里2L对应的二进制值就是这个.

  • 0x02: 关于classDescFlags的定义在协议文档是这样的:

The flag byte classDescFlags may include values of

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;

所以0x02代表了可序列化.

  • 0x0001: 这一位代表了类中域的个数,在我们的Pet类里,只有一个域就是int paws,所以为1.
  • 0x49: 这个二进制对应的ASCII值是I,这在规范里有定义,我们看下规范定义的是什么:

(B' for byte, C' for char, D' for double, F' for float, I' for int, > J' for long, L' for non-array object types, S' for short, Z' for boolean, and [` for arrays)

所以I的意思就是域的类型int型,跟我们在Pet类中的定义一样.

  • ** 0x00 04

    Java序列化格式详解的更多相关文章

    1. Java 序列化Serializable详解

      Java 序列化Serializable详解(附详细例子) Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连 ...

    2. Java 序列化Serializable详解(附详细例子)

      Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization ...

    3. java 序列化Serializable 详解

      Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是 ...

    4. Java 序列化Serializable详解(附详细例子)

      Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是 ...

    5. php 序列化(serialize)格式详解

      1.前言 PHP (从 PHP 3.05 开始)为保存对象提供了一组序列化和反序列化的函数:serialize.unserialize.不过在 PHP 手册中对这两个函数的说明仅限于如何使用,而对序列 ...

    6. Java字节码(.class文件)格式详解(一)

      原文链接:http://www.blogjava.net/DLevin/archive/2011/09/05/358033.html 小介:去年在读<深入解析JVM>的时候写的,记得当时还 ...

    7. C# XML序列化与反序列化与XML格式详解

      1.https://www.cnblogs.com/sandyliu1999/p/4844664.html XML是有层次结构的,序列化实际就是内存化,用连续的结构化的内存来存储表示一个对象,那么这两 ...

    8. java分享第十五天(log4j 格式详解)

      log4j 格式详解  log4j.rootLogger=日志级别,appender1, appender2, -. 日志级别:ALL<DEBUG<INFO<WARN<ERRO ...

    9. [转帖]ECC公钥格式详解

      ECC公钥格式详解 https://www.cnblogs.com/xinzhao/p/8963724.html 本文首先介绍公钥格式相关的若干概念/技术,随后以示例的方式剖析DER格式的ECC公钥, ...

    随机推荐

    1. 关于MYSQL四种引擎

      你能用的数据库引擎取决于mysql在安装的时候是如何被编译的.要添加一个新的引擎,就必须重新编译MYSQL.在缺省情况下,MYSQL支持三个引擎:ISAM.MYISAM和HEAP.另外两种类型INNO ...

    2. C++面试中关于sizeof问题总结

      原文:http://blog.sina.com.cn/s/blog_7c983ca60100yfdv.html#SinaEditor_Temp_FontName (1)      sizeof是操作符 ...

    3. 检查Chunksum与Chunk Data之间的缓冲区发送到DataNode节点

      我们会看到左边"iOS Apps"下面有四个选项:"Certificates"."Identifiers"."Devices&qu ...

    4. myeclipse2014激活

      MyEclipse2014破解教程 一. 在破解myeclipse2014之前,要先把环境变量配置好: 1)打开我的电脑--属性--高级--环境变量 2)新建系统变量JAVA_HOME 和CLASSP ...

    5. C语言题库的上机题

      1.编写函数,实现从键盘上输入一个小写字母,将其转化为大写字母. #include<stdio.h> int zhuanhua(char s); void main(){ char s; ...

    6. BeanUtils: 威力和代价(转载)

      转自:http://blog.sina.com.cn/s/blog_ab3fbf1b0101jbxz.html Apache Jakarta Commons项目非常有用.我曾在许多不同的项目上或直接或 ...

    7. nodejs研究笔记

      首先呢,安装 1:安装mongodb-win32-x86_64-3.2.5-signed.msi 2:手动创建目录 如 C:\data\db 及 C:\data\dbConf 3:管理员身份运行 cm ...

    8. GDB常用命令

      一. gdb使用流程 1.编译生成可执行文件 gcc -g hello.c -o hello 2.启动gdb gdb hello 3. 在main处设置断点 break main 4.运行程序 run ...

    9. 20151013 C# 第一篇 流程控制语句

      20151013 流程控制语句: 1.选择语句 if … else if...else 选择语句 if(布尔表达式){  语句块:} if(布尔表达式){  语句块1:}else{  语句块2:} i ...

    10. spring4+hibernate4+maven环境搭建

      本文主要介绍利用maven搭建spring4+hibernate4开发环境. 首先我们创建一个maven项目,具体步骤就不详细介绍了,看看我们pom.xml文件 <project xmlns=& ...