CN115167869A - 一种Java对象序列化和反序列化的方法、电子设备及介质 - Google Patents
一种Java对象序列化和反序列化的方法、电子设备及介质 Download PDFInfo
- Publication number
- CN115167869A CN115167869A CN202210757355.XA CN202210757355A CN115167869A CN 115167869 A CN115167869 A CN 115167869A CN 202210757355 A CN202210757355 A CN 202210757355A CN 115167869 A CN115167869 A CN 115167869A
- Authority
- CN
- China
- Prior art keywords
- type
- schema
- storing
- serialization
- byte
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/52—Binary to binary
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/53—Decompilation; Disassembly
Landscapes
- Engineering & Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
本发明提出一种Java对象序列化和反序列化的方法,能够在异构环境下工作且可以根据不同传输场景选择不同传输策略,且在将二进制码反序列化为对象时支持合理的数据类型的转换,数据传输和持久化存储效率较快的同时序列化后的数据占用空间较小。通过本发明,用户可以实现对Java中原生类型、常用基本类型、基本类型数组、基本集合以及类对象的序列化与反序列化,也可以实现合理数据类型的转换。
Description
技术领域
本发明涉及数据处理技术领域,具体为一种将Java对象序列化为二进制码和将二进制码反序列化为Java对象的方法、电子设备及介质。
背景技术
序列化是指堆内存中的Java对象数据,通过某种方式把对象存储到磁盘文件中,或者传递给其他网络节点的过程,通常是将数据结构或者对象转换成二进制的过程。反序列化指把磁盘文件中的对象数据或者把网络节点上的对象数据,恢复成Java对象的过程,即将在序列化过程中生成的二进制串转换成数据结构或者对象的过程。当两个进程在进行远程通信时,彼此可以发送各种类型的数据,无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为对象。因此,对Java对象的序列化和反序列化在需要频繁进行数据交换和存储的大数据、电子通信等领域具有广阔的应用前景。
在大数据分析领域中,对象的序列化和反序列化是一项基本操作,是分布式计算节点与潜在非统一执行环境之间高效通信的一个基本特性。序列化反序列化操作广泛应用于大数据分析框架中,用于远程过程调用和洗牌等海量数据传输。当今大数据分析框架中的海量数据操作,例如map/reduce,shufflfle大量使用序列化反序列化操作。在大型web应用中,为解决这些应用中的可能出现的间歇性故障,其应用程序中的数据序列化是一个重要的环节,序列化和反序列化几乎是工程师们每天都要面对的事情,恰当的序列化协议不仅可以提高系统的通用性、强健性、安全性、优化系统性能,而且会让系统易于调试、便于扩展。电子通信领域,序列化技术一直是数据交换的重要组成部分。由于电子通信需要进行频繁的数据传输,在数据传输时发送方需要将对象序列化为二进制码,接收方需要将二进制码反序列化为对象,因此,提高序列化反序列化的速度便能大幅提高数据传输的效率。
目前针对Java对象的序列化和反序列化方法灵活性较差,缺乏与对应场景相对应的序列化流发送策略,数据传输和处理的效率低。
发明内容
针对现有技术存在的问题,本发明提出一种Java对象序列化和反序列化的方法、电子设备及介质,能够在异构环境下适应多种传输情况,包括对Java中原生类型(boolean、short、int等)、常用基本类型(String、Date、BigInteger等)、基本类型数组(boolean[]、short[]、int[]等)、基本集合以及类对象的序列化与反序列化。
本发明的技术方案为:
所述一种Java对象序列化和反序列化的方法,序列化包括以下步骤:
步骤1:初始化用于存储序列化中的枚举类型和类对象结构的对象schema和字节数组封装类的对象dataBuffer;对象dataBuffer中的字节数组buffer用于存储本次序列化的结果;
步骤2:生成序列化数据
首先对需要序列化的对象进行检查,检查是否是AsType,如果是AsType,则将值转化为AsType对应的类型;所述AsType是为了传输优化而定义的一套接口,能够实现将一种数据类型当成其他一种数据类型来处理;
然后根据需要序列化的对象类型分别采取不同的序列化策略进行序列化,得到序列化结果数组buffer;对象类型为:直接转换类型,基本集合、文件或枚举类型,类对象;
步骤3:利用得到的序列化结果数组buffer生成结果数据;
反序列化包括以下步骤:
步骤4:在序列化的最终结果数组中按顺序读出schema的内容所占的字节长度、序列化结果总字节长度、schema的内容和序列化结果;
步骤5:根据需要反序列化的数据类型采取不同的反序列化策略,实现反序列化的过程。
进一步的,步骤1中,对象schema分为存储枚举类型结构的EnumSchema和存储类对象结构的ObjectSchema两种类型。
进一步的,步骤2中,所述直接转换类型包括Java的原生类型、Java的常用基本类型以及Java的基本类型数组;如果对象类型是直接转换类型,先将该对象的类型编码存储到dataBuffer中的字节数组buffer中,再对该对象进行序列化,并将序列化后的结果存入字节数组中。
进一步的,步骤2中,所述基本集合、文件或枚举类型包括链表List类型、数组Array类型、Map类型、集合Set类型、文件File类型或枚举Enum类型;
如果该对象类型为链表类型、数组类型、Map类型或集合类型,先在字节数组buffer中存储当前对象类型对应的字节编码,再存储该对象的元素个数,最后遍历该对象中的每个元素,对该对象中的每一个元素进行序列化;
如果该对象类型为文件类型,先在字节数组buffer中存储当前对象类型对应的字节编码,接着在字节数组buffer中存储文件名称长度和序列化后的文件名称,最后存储文件内容所占的字节长度和序列化后的文件内容;
如果该对象类型为枚举类型,先判断该枚举类型对应的enumSchema是否已经存在,若不存在,则将该枚举类型的名称及对应的enumSchema以键:值的形式存入哈希表schemas中,其中enumSchema存储枚举类型定义中的每一个名称和该名称在定义中的顺序号;若该枚举类型对应的enumSchema已存在,则首先在字节数组buffer中存储枚举类型对应的字节编码,接着存储该枚举类型对应的enumSchema在哈希表schemas中的顺序号,最后存储该枚举变量的取值在枚举类型定义中对应的顺序号。
进一步的,步骤2中,在对类对象进行序列化时,首先判断该类对应的objectSchema是否已经存在,若不存在,则将该类对象对应的类名及对应的objectSchema以键:值的形式存入哈希表schemas中,其中objectSchema存储该类的所有可用属性的名称和该属性的顺序号;若该类对应的objectSchema已存在,则:
先新建一个字节数组objectContent;
遍历该类中的所有可用属性,对于每一个属性,首先在字节数组objectContent中存储该属性在类中的顺序号,再对每一个属性进行序列化;遍历结束后,整个类的所有属性完成序列化,并将结果存储到字节数组objectContent;
在字节数组buffer中,首先存储类对象的类型编码,接着存储该类对应的objectSchema在哈希表schemas中的顺序号,再存储字节数组objectContent的大小,最后存储整个字节数组objectContent的内容,整个类对象的序列化过程结束。
进一步的,步骤3中,生成整个序列化过程的结果数据的过程为:
步骤3.1:新建一个字节数组封装类的对象rst,该对象中的字节数组用来存储本次序列化的结果数据,新建字节数组schemaBytes用来存储所有schema的内容,新建字节数组dataBytes用来存储序列化结果数组buffer的内容;
步骤3.2:遍历本次序列化过程中的所有schema,对于每一个schema,在字节数组schemaBytes中首先存储该schema的顺序号,再存储该schema的类型,然后存储该schema内容所占的字节数,最后存储该schema的内容;遍历结束后,所有schema的结果数据被存储到字节数组schemaBytes中;
步骤3.3:将序列化结果数组buffer的内容复制到字节数组dataBytes中;
步骤3.4:在对象rst的字节数组中,首先存储字节数组schemaBytes的长度,接着存储字节数组dataBytes的长度,再存储字节数组schemaBytes的内容,最后存储字节数组dataBytes的内容,整个序列化过程的结果数据存储完成。
进一步的,步骤4中,若schema的内容部分包含多个schema,则从字节数组中的schema内容部分分离每个schema的顺序号及内容,并将schema的顺序号及对应的enumSchema或objectSchema以键:值的形式存入哈希表schemas中。
进一步的,步骤5中,所述反序列化的过程包括:
步骤5.1:读取字节数组第一个字节,获得该对象的数据类型,从字节数组第二个字节开始获取需要反序列化的数据值;
步骤5.2:检查是否存在想要转换成的对象类型,如果存在,则针对不同的类型选择相应的数据结构存储反序列化后的对象;
步骤5.3:检查需要反序列化的对象类型是否为直接转换类型,若是,则获取该类型对应的序列化反序列化处理器,处理器首先读取偏移量位置存放的数据,再对该对象进行反序列化,得到反序列化后的对象;
步骤5.4:判断需要反序列化的对象类型是否为链表List类型、Map类型、集合Set类型、文件File类型或枚举Enum类型;
若需要反序列化的对象类型为链表List类型、Map类型、集合Set类型,则首先从序列化结果数组中读取元素个数并转为int类型,接着遍历读出每个元素的内容并进行反序列化,再将得到的元素存入相应类型的对象中;其中Map类型中每个元素是键:值的形式,在对Map进行反序列化时,键和值分别进行反序列化;
若需要反序列化的对象类型为文件类型,则从序列化结果数组中读取文件名称长度所占的字节长度,接着按照该长度读取文件名称,再读取文件内容所占的字节长度,并根据该长度读取文件内容;
若需要反序列化的对象类型为枚举类型,则从序列化结果数组中读取该枚举类型对应的schema顺序号,接着读取该枚举变量的取值在枚举类型定义中对应的顺序号,再根据schema顺序号从哈希表schemas中获取该枚举类型对应的enumSchema,最后通过取值在枚举类型定义中对应的顺序号从enumSchema中获取该枚举值的名称;
步骤5.5:判断需要反序列化的对象类型是否为类对象,若是,首先按顺序从序列化结果数组中分离schema顺序号、该对象的序列化内容所占的字节长度;再根据schema的顺序号从哈希表schemas中获取该类对应的objectSchema;之后从该类对应的objectSchema获取类名称,从而通过Java的forName函数创建该类的对象;从序列化结果数组中遍历读取每个类属性的顺序号,通过顺序号获取该属性的名称,接着进行反序列化得到该属性的值,并在创建好的该类对象中设置该属性的值;类属性遍历结束后,得到反序列化后的类对象。
一种电子设备,包括处理器以及存储程序的存储器,所述程序包括指令,所述指令在由所述处理器执行时使所述处理器执行上述方法。
一种存储程序的计算机可读存储介质,所述程序包括指令,所述指令在由电子设备的处理器执行时,致使所述电子设备执行上述方法。
通过本发明,用户可以在不同的异构数据传输场景下选择相应的序列化流发送策略,极大地提高了序列化过程中的灵活性。与此同时,本发明对数据类型采用字节编码进行存储和传输,与传统的字符串编码相比,在保证较快效率的同时序列化后生成的结果数据占用空间也较小。用户可以将本发明与大数据的数据传输和数据操作相结合,在数据量巨大的情况下能大幅缩短数据传输和处理的效率;也可以将本发明应用到大型web开发中,提高大型web应用的性能;用户还可以将本发明与电子通信领域结合,使用本发明的序列化反序列化方法传输数据,提高通信效率。综上,本发明在序列化反序列化数据类型、效率、占用空间等方面,为网络通信和数据持久化提供了坚实的技术基础。本发明可运用于需要频繁使用序列化反序列化技术的领域,例如,大数据领域、web开发领域、电子通信领域等。
有益效果
本发明实现了一种能够在异构环境下工作且可以根据不同传输场景选择不同传输策略的序列化方法,且在将二进制码反序列化为对象时支持合理的数据类型的转换(如反序列化链表时转换为数组),数据传输和持久化存储效率较快的同时序列化后的数据占用空间较小。通过本发明,用户可以实现对Java中原生类型(boolean、short、int等)、常用基本类型(String、Date、BigInteger等)、基本类型数组(boolean[]、short[]、int[]等)、基本集合以及类对象的序列化与反序列化,也可以实现合理数据类型的转换。
用户可以将本发明与大数据、web开发、电子通信等领域结合,例如,将本发明应用于分布式计算节点之间的便携、无损通信,在进行节点间数据传输时,发送方节点首先将大量对象序列化为字节流;然后,接收方节点从序列化字节流重构对象,本发明的序列化与反序列化方法能较大程度地提高数据传输的效率。本发明也可以与大型web开发结合,由于大型web应用在运行的过程中需要频繁进行数据传输和数据的本地化存储,使用本发明可以显著提高大型web应用的性能。本发明还能够与电子通信领域结合,节省序列化与反序列化花费的时间,有效提高电子通信中数据传输的效率。
本发明的附加方面和优点将在下面的描述中部分给出,部分将从下面的描述中变得明显,或通过本发明的实践了解到。
附图说明
本发明的上述和/或附加的方面和优点从结合下面附图对实施例的描述中将变得明显和容易理解,其中:
图1是实施例的序列化流结构示意图。
图2是实施例的不同场景下序列化流发送策略示意图。
具体实施方式
本发明是一种能在异构环境下工作且能根据不同传输场景选择不同传输策略的序列化方法。本发明序列化后形成的序列化流是纯二进制的,因此可以在异构的场景下使用。
本发明使用schema存储序列化中枚举类型和类对象的结构,分为存储枚举类型结构的EnumSchema和存储类对象结构的ObjectSchema两种类型。
本发明形成的序列化流分为较为独立的两个部分:所有的schema组成了序列化流的头部,数据值序列化后形成了序列化流的数据部分。其中序列化流的头部是可拆卸的,最大程度地将对象内部的数据类型和数据值剥离开,因此支持根据不同的传输场景选择不同的传输策略,极大地提高了序列化反序列化过程中的灵活性。在数据传输的过程中,已经传输过的类结构可以不用再传输,或者提前将本次传输需要的类结构存储在远程服务上,减少了序列化流的体量。数据传输过程结束后,接收节点可以并行地反序列化序列化流的头部和数据部分,提高了反序列化过程的效率。
本发明对一个嵌套调用的类对象进行序列化时,以图1(a)为例,ClassA的对象中包含ClassB和ClassC的对象,并含有一个枚举类型,其中ClassB的对象包含ClassD的对象。对于这样一个嵌套调用的类对象,首先将代码片段转换为相应的对象图,如图1(b)所示。本发明序列化后的字节流结构如图1(c)所示,在序列化过程中,对于类对象类型,将该类对应的objectschema存储到序列化流的头部,每个类仅需存储一次,并根据存储顺序产生该类类型对应的id。接着对类对象进行递归拆分,对于类对象中的基本类型直接序列化为字节流,对于无法直接序列化的类对象类型、集合类型等,对这些类型同样进行递归拆分,直至全部拆解为基本类型。对于每个枚举类型,以相应的enumschema存储结构,并和objectschema同样存储到序列化流的头部。
在反序列化过程中,首先对序列化后的字节流拆分为头部和数据部分,将头部反序列化为表示类对象的objectschema和表示枚举类型结构的enumschema,并根据schema对数据部分进行反序列化。与序列化过程类似,反序列化过程也采取递归的方式对类对象进行反序列化,对于基本类型,直接反序列化为相应的类型,对于无法直接反序列化的类对象类型、集合类型等,对这些类型进行递归拆分,直至全部拆解为基本类型,并对拆解后得到的基本类型进行反序列化。
本发明可以根据不同的传输场景选择不同的数据传输策略。对于少量数据传输的情况,此时头部对整个数据传输效率的影响不大,可以将头部和数据部分串行发送,如图2(a)所示;当需要进行大量数据传输时,如大数据、电子信息等领域的数据传输过程中,由于绝大多数情况是对于同一批类的对象的多次传输,因此可以将这两个部分分别传输,如图2(b)所示。对于发送节点来说,只需在首次传输时将本次传输过程中需要的所有schema作为序列化流的头部发送,或者将头部提前发送到远程服务上,如图2(c)所示,在整个数据传输过程中,发送节点仅需发送一次序列化的头部,相应地,接收节点也仅需接收一次,其余时间均用作传输数据值。由于本发明将序列化流分为了可拆卸的头部和作为传输主体的数据部分,因此在接收节点接收完所有的序列化流后,可以选择将头部和数据部分分别进行反序列化,数据结构的恢复和数据值的填充同步进行。
本发明还使用一种自定义的长度编码法来有效减少序列化流的大小。对象的序列化过程需要大量存储长度,如对数组、链表等基本集合类型进行序列化时需要首先存储该基本集合类型的长度;在存储一个类对象的schema时也需要首先存储该schema的长度(即在序列化后字节数组中的所占字节的位数)。传统的序列化过程将长度按照原本的long类型进行存储,在真实的数据传输场景中,长度值往往不会很大,使用long进行存储无疑在绝大多数情况下都产生了空间的浪费。为了解决这一问题,本发明采用变长的整型来存储序列化过程中用到的所有长度。对于一个表示长度的long类型,本发明首先会检查实际大小,根据long的有效值位数构建一个字节数组,如当long为257时,有效值为9位,构建两个字节大小的字节数组。在此种情况下使用本发明的长度编码法相较于传统序列化方法节省了两个字节的空间大小。考虑到长度这一属性在序列化过程中的普遍性,本发明长度编码法能大大减少序列化流的大小。
下面给出序列化和反序列化的具体步骤:
(一)序列化
为达到支持Java对象中多种数据类型序列化的目的,首先初始化一个用于存储序列化中的枚举类型和类对象结构的schema,和一个字节数组封装类的对象dataBuffer,对象dataBuffer中的字节数组buffer用于存储本次序列化的结果;接着根据需要序列化的数据类型采取不同的序列化策略;最后在生成本次序列化的结果数据。本发明中序列化的步骤描述如下:
步骤1:初始化
初始化一个MotpBuilderSchema类的对象schema和一个字节数组封装类MByteBuffer的对象dataBuffer。其中schema用于存储序列化中枚举类型和类对象的结构,分为存储枚举类型结构的EnumSchema和存储类对象结构的ObjectSchema两种类型;对象dataBuffer中的字节数组buffer用于存储本次序列化的结果。
步骤2:生成序列化数据
1)对象化简
Motp首先对需要序列化的对象进行检查,检查是否是AsType,如果是AsType,则将值转化为AsType对应的类型。AsType是Motp为了传输优化而定义的一套接口,可以把一种数据类型当成其他一种数据类型来处理。如传输一个点的坐标(x,y)时,常规的传输方法需要分别传输x字段和y字段,Motp使用长整型long类型存储该坐标,前32位存储x坐标,后32位存储y坐标。当对该long类型序列化时,就需要还原成原来x字段和y字段的形式,再进行后续的序列化步骤。
2)判断是否是直接转换类型
Motp检查需要序列化的对象类型是否为直接转换类型,直接转换类型包括Java的原生类型(boolean、short、int等)、Java的常用基本类型(String、Date、BigInteger等)以及Java的基本类型数组(boolean[]、short[]、int[]等)。
对于直接转换类型:
(1)存储该对象的类型编码
Motp将每种数据类型按一个字节的大小进行编码(如int类型以0x03进行编码),Motp获取该类型对应的编码后将该对象的类型编码存储到dataBuffer中的字节数组buffer中。
(2)对该对象进行序列化
Motp对该类型的对象进行序列化,并将序列化后的结果存入字节数组中。以int类型为例,appendData函数检查到int类型为直接转换类型后,获取int类型的处理器MotpInt32Processer,并调用appendInt函数对int类型的对象进行序列化。由于int类型占4个字节,所以序列化后在字节数组中占4个索引的位置,字节数组中第1个索引的位置存储int类型的高8位,所以将int右移24位后与0xFF做与运算,得到int类型的高8位,其他字节以类似的情况计算后存储。
3)判断是否为基本集合、文件或枚举类型
Motp判断需要被序列化的对象是否为链表List类型、数组Array类型、Map类型、集合Set类型、文件File类型或枚举Enum类型。
(1)基本集合类型
若该对象为链表、数组、Map或集合类型,首先在字节数组buffer中存储当前对象类型对应的字节编码,再存储该对象的元素个数,最后遍历该对象中的每个元素,调用appendData函数,对该对象中的每一个元素进行序列化,该对象的序列化过程结束。特别地,由于Map中每个元素是键:值的形式,在遍历Map时,键和值需要分别调用appendData函数进行序列化。
(2)文件类型
若该对象为文件类型,首先在字节数组buffer中存储当前对象类型对应的字节编码,接着在字节数组buffer中存储文件名称长度和序列化后的文件名称,最后存储文件内容所占的字节长度和序列化后的文件内容。
(3)枚举类型
若该对象为枚举类型,首先判断该枚举类型对应的enumSchema是否已经存在,若不存在,则将该枚举类型的名称及对应的enumSchema以键:值的形式存入哈希表schemas(存储所有的enumSchema和objectSchema)中,其中enumSchema存储着枚举类型定义中的每一个名称和该名称在定义中的顺序号(从0开始,逐次加1)。若该枚举类型对应的enumSchema已存在,则首先在字节数组buffer中存储枚举类型对应的字节编码,接着存储该枚举类型对应的enumSchema在哈希表schemas中的顺序号(值为存储位置的索引值加1,相当于在哈希表schemas中该enumSchema的id),最后存储该枚举变量的取值在枚举类型定义中对应的顺序号。
4)对类对象进行序列化
在对类对象进行序列化时,首先判断该类对应的objectSchema是否已经存在,若不存在,则将该类对象对应的类名及对应的objectSchema以键:值的形式存入哈希表schemas(存储所有的enumSchema和objectSchema)中,其中objectSchema存储该类的所有可用属性(包括从父类继承的,但不包括已被覆盖的父类属性)的名称和该属性的顺序号(从1开始,逐次加1)。若该类对应的objectSchema已存在,则:
(1)新建一个字节数组objectContent。
(2)遍历该类中的所有可用属性,对于每一个属性,首先在字节数组objectContent中存储该属性在类中的顺序号,再调用appendData函数,对每一个属性进行序列化。遍历结束后,整个类的所有属性完成序列化,并将结果存储到字节数组objectContent。
(3)在字节数组buffer中,首先存储类对象的类型编码,接着存储该类对应的objectSchema在哈希表schemas中的顺序号(值为存储位置的索引值加1,相当于在哈希表schemas中该objectSchema的id),再存储字节数组objectContent的大小,最后存储整个字节数组objectContent的内容,整个类对象的序列化过程结束。
步骤3:生成结果数据
在得到序列化结果数组buffer后,Motp生成整个序列化过程的结果数据。在生成结果数据时:
1)数据结构初始化
Motp新建一个字节数组封装类MByteBuffer的对象rst,该对象中的字节数组用来存储本次序列化的结果数据,新建字节数组schemaBytes用来存储所有schema的内容,新建字节数组dataBytes用来存储序列化结果数组buffer的内容。
2)填充字节数组schemaBytes
遍历本次序列化过程中的所有schema,对于每一个schema,在字节数组schemaBytes中首先存储该schema的顺序号,再存储该schema的类型(enumSchema或objectSchema),再存储该schema内容所占的字节数,最后存储该schema的内容。遍历结束后,所有schema的结果数据被存储到字节数组schemaBytes中。
3)填充字节数组dataBytes
将经过步骤1、2获取的序列化结果数组buffer的内容复制到字节数组dataBytes中。
4)将结果数据存储到对象rst的字节数组中
在对象rst的字节数组中,首先存储字节数组schemaBytes的长度,接着存储字节数组dataBytes的长度,再存储字节数组schemaBytes的内容,最后存储字节数组dataBytes的内容,整个序列化过程的结果数据存储完成。
(二)反序列化
为达到支持Java对象中多种数据类型反序列化的目的,首先在序列化的最终结果数组中按顺序读出schema的内容所占的字节长度、序列化结果总字节长度、schema的内容和序列化结果;接着根据需要反序列化的数据类型采取不同的反序列化策略。
本发明中反序列化的步骤描述如下:
步骤4:初始化
由于反序列化是序列化的逆向过程,因此,反序列化需要在序列化的最终结果数组按顺序读出schema内容所占的字节长度、序列化结果所占字节总长度、schema内容和序列化结果。其中schema的内容部分可能包含多个schema(enumSchema或objectSchema),因此需要从字节数组中的schema内容部分分离每个schema的顺序号及内容,并将schema的顺序号及对应的enumSchema或objectSchema以键:值的形式存入哈希表schemas中。
步骤5:生成反序列化对象
在生成反序列化对象时,根据schema内容所占字节长度、序列化结果所占字节总长度、schema内容和序列化结果,调用readData函数实现反序列化的过程。
1)分离数据类型和数据值
在对一个对象进行序列化时,首先需要在字节数组中存储该对象的数据类型编码,再存储该对象的序列化结果,因此,在反序列化的过程中首先需要分离数据类型编码和数据的值。由于Motp将每种数据类型按一个字节的大小进行编码,在读取数据类型时只需读取第一个字节,即可获得该对象的数据类型,字节数组中从第二个字节开始的字节即为需要反序列化的数据值。
2)检查是否存在想要转换成的对象类型
在反序列化时可能会存在想要转换成的对象类型,如序列化后的链表对象经过反序列化可以转换成数组、集合对象;序列化后的集合对象经过反序列化可以转换成数组、链表对象。对于存在想要转换成的对象类型的情况,仅需针对不同的类型选择相应的数据结构存储反序列化后的对象即可,因此反序列化的其余步骤均在不存在想要转换成的对象类型的情况下展开描述。
3)判断是否是直接转换类型
Motp检查需要反序列化的对象类型编码是否为直接转换类型,直接转换类型包括Java的原生类型(boolean、short、int等)、Java的常用基本类型(String、Date、BigInteger等)以及Java的基本类型数组(boolean[]、short[]、int[]等)。若需要反序列化的对象类型为直接转换类型,Motp获取该类型对应的序列化反序列化处理器(如int类型的处理器为MotpInt32Processer),处理器首先读取偏移量位置存放的数据,再对该对象进行反序列化,得到反序列化后的对象。
以int类型为例,Motp检查到int类型为直接转换类型后,获取int类型的处理器MotpInt32Processer,并调用readInt函数对int类型的对象进行反序列化。
readInt函数首先调用assetOffset函数确保偏移量不超过缓冲区自身大小,由于int类型占4个字节,所以assetOffset的参数为4。接着获取字节数组中第1个字节,向左移8位后与下一个字节做或运算,依此类推,左移4次并做3次或运算后得到int的值。
4)判断是否是基本集合、文件或枚举类型
Motp判断需要反序列化的对象类型编码是否为链表List类型、Map类型、集合Set类型、文件File类型或枚举Enum类型。
(1)基本集合
若需要反序列化的对象类型编码为链表List类型、Map类型、集合Set类型,首先从序列化结果数组中读取元素个数并转为int类型,接着遍历(通过读取出的元素个数控制遍历次数)读出每个元素的内容并调用readData函数进行反序列化,再将得到的集合元素存入相应类型的基本集合中。特别地,由于Map中每个元素是键:值的形式,在对Map进行反序列化时,键和值需要分别调用readData函数进行反序列化。
(2)文件类型
若需要反序列化的对象类型编码为文件类型,首先从序列化结果数组中读取文件名称长度所占的字节长度,接着按照该长度读取文件名称,再读取文件内容所占的字节长度,并根据该长度读取文件内容。
(3)枚举类型
若需要反序列化的对象类型编码为枚举类型,首先从序列化结果数组中读取该枚举类型对应的schema顺序号,接着读取该枚举变量的取值在枚举类型定义中对应的顺序号,再根据schema顺序号从哈希表schemas中获取该枚举类型对应的enumSchema,最后通过取值在枚举类型定义中对应的顺序号从enumSchema中获取该枚举值的名称。
5)判断是否是类对象
若需要反序列化的对象为类对象,则:
(1)按顺序从序列化结果数组中分离schema顺序号、该对象的序列化内容所占的字节长度。
(2)根据schema的顺序号从哈希表schemas中获取该类对应的objectSchema。
(3)从该类对应的objectSchema获取类名称,从而通过Java的forName函数创建该类的对象。
(4)从序列化结果数组中遍历读取每个类属性的顺序号,通过顺序号获取该属性的名称,接着调用readData函数进行反序列化得到该属性的值,并在创建好的该类对象中设置该属性的值。类属性遍历结束后,得到反序列化后的类对象。
下面给出具体的实现代码:
对于序列化部分:
1)整个序列化的流程代码如下:
2)实现序列化功能的函数appendData代码如下:
3)在序列化的步骤2中需要判断序列化的对象是否是直接转换类型,根据对象类型会选择相应的Motp序列化反序列化处理器,数据类型与序列化反序列化处理器的对应关系如下:
4)对int类型的序列化代码如下:
5)对List类型的序列化代码如下:
6)对类对象的序列化代码如下:
对于反序列化部分:
1)整个反序列化的流程代码如下:
2)实现反序列化功能的函数readData代码如下:
3)对int类型的反序列化代码如下:
4)对List类型的反序列化代码如下:
6)对类对象的反序列化代码如下:
尽管上面已经示出和描述了本发明的实施例,可以理解的是,上述实施例是示例性的,不能理解为对本发明的限制,本领域的普通技术人员在不脱离本发明的原理和宗旨的情况下在本发明的范围内可以对上述实施例进行变化、修改、替换和变型。
Claims (10)
1.一种Java对象序列化和反序列化的方法,其特征在于:
序列化包括以下步骤:
步骤1:初始化用于存储序列化中的枚举类型和类对象结构的对象schema和字节数组封装类的对象dataBuffer;对象dataBuffer中的字节数组buffer用于存储本次序列化的结果;
步骤2:生成序列化数据
首先对需要序列化的对象进行检查,检查是否是AsType,如果是AsType,则将值转化为AsType对应的类型;所述AsType是为了传输优化而定义的一套接口,能够实现将一种数据类型当成其他一种数据类型来处理;
然后根据需要序列化的对象类型分别采取不同的序列化策略进行序列化,得到序列化结果数组buffer;对象类型为:直接转换类型,基本集合、文件或枚举类型,类对象;
步骤3:利用得到的序列化结果数组buffer生成结果数据;
反序列化包括以下步骤:
步骤4:在序列化的最终结果数组中按顺序读出schema的内容所占的字节长度、序列化结果总字节长度、schema的内容和序列化结果;
步骤5:根据需要反序列化的数据类型采取不同的反序列化策略,实现反序列化的过程。
2.根据权利要求1所述一种Java对象序列化和反序列化的方法,其特征在于:步骤1中,对象schema分为存储枚举类型结构的EnumSchema和存储类对象结构的ObjectSchema两种类型。
3.根据权利要求1所述一种Java对象序列化和反序列化的方法,其特征在于:步骤2中,所述直接转换类型包括Java的原生类型、Java的常用基本类型以及Java的基本类型数组;如果对象类型是直接转换类型,先将该对象的类型编码存储到dataBuffer中的字节数组buffer中,再对该对象进行序列化,并将序列化后的结果存入字节数组中。
4.根据权利要求2所述一种Java对象序列化和反序列化的方法,其特征在于:步骤2中,所述基本集合、文件或枚举类型包括链表List类型、数组Array类型、Map类型、集合Set类型、文件File类型或枚举Enum类型;
如果该对象类型为链表类型、数组类型、Map类型或集合类型,先在字节数组buffer中存储当前对象类型对应的字节编码,再存储该对象的元素个数,最后遍历该对象中的每个元素,对该对象中的每一个元素进行序列化;
如果该对象类型为文件类型,先在字节数组buffer中存储当前对象类型对应的字节编码,接着在字节数组buffer中存储文件名称长度和序列化后的文件名称,最后存储文件内容所占的字节长度和序列化后的文件内容;
如果该对象类型为枚举类型,先判断该枚举类型对应的enumSchema是否已经存在,若不存在,则将该枚举类型的名称及对应的enumSchema以键:值的形式存入哈希表schemas中,其中enumSchema存储枚举类型定义中的每一个名称和该名称在定义中的顺序号;若该枚举类型对应的enumSchema已存在,则首先在字节数组buffer中存储枚举类型对应的字节编码,接着存储该枚举类型对应的enumSchema在哈希表schemas中的顺序号,最后存储该枚举变量的取值在枚举类型定义中对应的顺序号。
5.根据权利要求2所述一种Java对象序列化和反序列化的方法,其特征在于:步骤2中,在对类对象进行序列化时,首先判断该类对应的objectSchema是否已经存在,若不存在,则将该类对象对应的类名及对应的objectSchema以键:值的形式存入哈希表schemas中,其中objectSchema存储该类的所有可用属性的名称和该属性的顺序号;若该类对应的objectSchema已存在,则:
先新建一个字节数组objectContent;
遍历该类中的所有可用属性,对于每一个属性,首先在字节数组objectContent中存储该属性在类中的顺序号,再对每一个属性进行序列化;遍历结束后,整个类的所有属性完成序列化,并将结果存储到字节数组objectContent;
在字节数组buffer中,首先存储类对象的类型编码,接着存储该类对应的objectSchema在哈希表schemas中的顺序号,再存储字节数组objectContent的大小,最后存储整个字节数组objectContent的内容,整个类对象的序列化过程结束。
6.根据权利要求1所述一种Java对象序列化和反序列化的方法,其特征在于:步骤3中,生成整个序列化过程的结果数据的过程为:
步骤3.1:新建一个字节数组封装类的对象rst,该对象中的字节数组用来存储本次序列化的结果数据,新建字节数组schemaBytes用来存储所有schema的内容,新建字节数组dataBytes用来存储序列化结果数组buffer的内容;
步骤3.2:遍历本次序列化过程中的所有schema,对于每一个schema,在字节数组schemaBytes中首先存储该schema的顺序号,再存储该schema的类型,然后存储该schema内容所占的字节数,最后存储该schema的内容;遍历结束后,所有schema的结果数据被存储到字节数组schemaBytes中;
步骤3.3:将序列化结果数组buffer的内容复制到字节数组dataBytes中;
步骤3.4:在对象rst的字节数组中,首先存储字节数组schemaBytes的长度,接着存储字节数组dataBytes的长度,再存储字节数组schemaBytes的内容,最后存储字节数组dataBytes的内容,整个序列化过程的结果数据存储完成。
7.根据权利要求1所述一种Java对象序列化和反序列化的方法,其特征在于:步骤4中,若schema的内容部分包含多个schema,则从字节数组中的schema内容部分分离每个schema的顺序号及内容,并将schema的顺序号及对应的enumSchema或objectSchema以键:值的形式存入哈希表schemas中。
8.根据权利要求1所述一种Java对象序列化和反序列化的方法,其特征在于:步骤5中,所述反序列化的过程包括:
步骤5.1:读取字节数组第一个字节,获得该对象的数据类型,从字节数组第二个字节开始获取需要反序列化的数据值;
步骤5.2:检查是否存在想要转换成的对象类型,如果存在,则针对不同的类型选择相应的数据结构存储反序列化后的对象;
步骤5.3:检查需要反序列化的对象类型是否为直接转换类型,若是,则获取该类型对应的序列化反序列化处理器,处理器首先读取偏移量位置存放的数据,再对该对象进行反序列化,得到反序列化后的对象;
步骤5.4:判断需要反序列化的对象类型是否为链表List类型、Map类型、集合Set类型、文件File类型或枚举Enum类型;
若需要反序列化的对象类型为链表List类型、Map类型、集合Set类型,则首先从序列化结果数组中读取元素个数并转为int类型,接着遍历读出每个元素的内容并进行反序列化,再将得到的元素存入相应类型的对象中;其中Map类型中每个元素是键:值的形式,在对Map进行反序列化时,键和值分别进行反序列化;
若需要反序列化的对象类型为文件类型,则从序列化结果数组中读取文件名称长度所占的字节长度,接着按照该长度读取文件名称,再读取文件内容所占的字节长度,并根据该长度读取文件内容;
若需要反序列化的对象类型为枚举类型,则从序列化结果数组中读取该枚举类型对应的schema顺序号,接着读取该枚举变量的取值在枚举类型定义中对应的顺序号,再根据schema顺序号从哈希表schemas中获取该枚举类型对应的enumSchema,最后通过取值在枚举类型定义中对应的顺序号从enumSchema中获取该枚举值的名称;
步骤5.5:判断需要反序列化的对象类型是否为类对象,若是,首先按顺序从序列化结果数组中分离schema顺序号、该对象的序列化内容所占的字节长度;再根据schema的顺序号从哈希表schemas中获取该类对应的objectSchema;之后从该类对应的objectSchema获取类名称,从而通过Java的forName函数创建该类的对象;从序列化结果数组中遍历读取每个类属性的顺序号,通过顺序号获取该属性的名称,接着进行反序列化得到该属性的值,并在创建好的该类对象中设置该属性的值;类属性遍历结束后,得到反序列化后的类对象。
9.一种电子设备,包括处理器以及存储程序的存储器,所述程序包括指令,其特征在于:所述指令在由所述处理器执行时使所述处理器执行权利要求1~8任一所述方法。
10.一种存储程序的计算机可读存储介质,所述程序包括指令,其特征在于:所述指令在由电子设备的处理器执行时,致使所述电子设备执行权利要求1~8任一所述方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202210757355.XA CN115167869A (zh) | 2022-06-29 | 2022-06-29 | 一种Java对象序列化和反序列化的方法、电子设备及介质 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202210757355.XA CN115167869A (zh) | 2022-06-29 | 2022-06-29 | 一种Java对象序列化和反序列化的方法、电子设备及介质 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN115167869A true CN115167869A (zh) | 2022-10-11 |
Family
ID=83489179
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202210757355.XA Pending CN115167869A (zh) | 2022-06-29 | 2022-06-29 | 一种Java对象序列化和反序列化的方法、电子设备及介质 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN115167869A (zh) |
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN116301666A (zh) * | 2023-05-17 | 2023-06-23 | 杭州数云信息技术有限公司 | Java对象序列化方法及其反序列化方法及装置、终端 |
-
2022
- 2022-06-29 CN CN202210757355.XA patent/CN115167869A/zh active Pending
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN116301666A (zh) * | 2023-05-17 | 2023-06-23 | 杭州数云信息技术有限公司 | Java对象序列化方法及其反序列化方法及装置、终端 |
CN116301666B (zh) * | 2023-05-17 | 2023-10-10 | 杭州数云信息技术有限公司 | Java对象序列化方法及其反序列化方法及装置、终端 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
TWI730654B (zh) | 部署和執行智能合約的方法及裝置 | |
CN110928483B (zh) | 数据存储、数据获取方法及设备 | |
US6324637B1 (en) | Apparatus and method for loading objects from a primary memory hash index | |
CN111884660B (zh) | 一种哈夫曼编码设备 | |
CN113839902B (zh) | 通信协议适配方法、装置、计算机设备和存储介质 | |
CN114564509B (zh) | 序列化方法、反序列化方法、设备、芯片以及介质 | |
CN113177034A (zh) | 一种跨平台统一的分布式图数据处理方法 | |
CN108886367A (zh) | 用于压缩和解压缩数据的方法、设备和系统 | |
US7404186B2 (en) | Signature serialization | |
CN115167869A (zh) | 一种Java对象序列化和反序列化的方法、电子设备及介质 | |
CN114331416A (zh) | 数据处理的方法、装置、电子设备及存储介质 | |
CN1426629A (zh) | 使用多个编码器的优化无损压缩的方法和装置 | |
CN114385146A (zh) | 一种简约的对象传输序列化方法及装置 | |
CN111600610B (zh) | 一种变长整数的通用编码方法、系统及电子设备 | |
CN113946453A (zh) | 数据处理方法及系统 | |
CN114385139B (zh) | 一种flink框架运行ETL流程的消息序列化以及比较方法与装置 | |
CN114024952B (zh) | 一种基于dl/t 698.45-2007协议的文件压缩传输方法 | |
CN113204683B (zh) | 信息重构方法和装置、存储介质及电子设备 | |
CN116561202A (zh) | 一种对象序列化处理的方法和装置 | |
CN115328679A (zh) | 异构函数库的自动化集成方法、计算设备及其系统 | |
CN114116074A (zh) | 一种高性能的数据序列化及反序列化系统 | |
CN113329076B (zh) | 数据传输方法、装置及系统、计算机设备、存储介质 | |
CN109413137A (zh) | 一种基于avro的PHP请求Python的方法 | |
CN110569487A (zh) | 一种基于高频率字符替代算法的Base64扩展编码方法及系统 | |
CN112200301B (zh) | 卷积计算装置及方法 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination |