我知道在一些分布式技术(如RPC)中,使用了术语“封送”,但不理解它与序列化有何不同。它们不是都在把对象转换成一系列的比特吗?

相关:

什么是序列化?

什么是对象编组?


当前回答

封送处理是指将函数的签名和参数转换为单字节数组。 专门用于RPC的目的。

序列化通常是指将整个对象/对象树转换为字节数组 封送处理将序列化对象参数,以便将它们添加到消息中并通过网络传递。 序列化也可以用于存储到磁盘

其他回答

来自编组(计算机科学)维基百科的文章:

The term "marshal" is considered to be synonymous with "serialize" in the Python standard library1, but the terms are not synonymous in the Java-related RFC 2713: To "marshal" an object means to record its state and codebase(s) in such a way that when the marshalled object is "unmarshalled", a copy of the original object is obtained, possibly by automatically loading the class definitions of the object. You can marshal any object that is serializable or remote. Marshalling is like serialization, except marshalling also records codebases. Marshalling is different from serialization in that marshalling treats remote objects specially. (RFC 2713) To "serialize" an object means to convert its state into a byte stream in such a way that the byte stream can be converted back into a copy of the object.

因此,编组除了保存对象的状态外,还在字节流中保存对象的代码库。

编组是告诉编译器数据将如何在另一个环境/系统上表示的规则; 例如;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;

正如您可以看到的,两个不同的字符串值表示为不同的值类型。

序列化将只转换对象内容,而不是表示(将保持不变)并遵守序列化规则(导出什么或不导出什么)。例如,私有值将不会被序列化,公共值是,对象结构将保持不变。

序列化vs编组

问题:对象属于某个进程(VM),其生命周期是相同的

序列化-将对象状态转换为字节流(JSON, XML…)用于保存,共享,转换…

编组-包含序列化+代码库。它通常用于远程过程调用(RPC) -> Java远程方法调用(Java RMI),在这里您可以调用托管在远程Java进程上的对象的方法。

codebase -是类定义的一个地方或URL,它可以被ClassLoader下载。CLASSPATH[About]作为一个本地代码库

JVM -> Class Loader -> load class definition
java -Djava.rmi.server.codebase="<some_URL>" -jar <some.jar>

非常简单的RMI图

Serialisation - state
Marshalling - state + class definition

官方文档

基础知识第一

Byte Stream - Stream is a sequence of data. Input stream - reads data from source. Output stream - writes data to destination. Java Byte Streams are used to perform input/output byte by byte (8 bits at a time). A byte stream is suitable for processing raw data like binary files. Java Character Streams are used to perform input/output 2 bytes at a time, because Characters are stored using Unicode conventions in Java with 2 bytes for each character. Character stream is useful when we process (read/write) text files.

RMI(远程方法调用)-一个API,提供了一种机制来创建java分布式应用程序。RMI允许一个对象调用另一个JVM中运行的对象的方法。


序列化和编组都被松散地用作同义词。这里有一些区别。

序列化——对象的数据成员被写入二进制形式或字节流(然后可以写入文件/内存/数据库等)。一旦将对象数据成员写入二进制形式,就不能保留任何关于数据类型的信息。

编组-对象被序列化(以二进制格式的字节流),附加数据类型+代码库,然后传递远程对象(RMI)。编组将数据类型转换为预先确定的命名约定,以便可以根据初始数据类型进行重构。

因此序列化是编组的一部分。

CodeBase是告诉Object的接收者该对象的实现可以在哪里找到的信息。任何认为自己可能会将一个对象传递给另一个之前可能没有见过它的程序的程序,都必须设置代码库,以便如果接收方在本地没有可用的代码,可以知道从哪里下载代码。在反序列化对象时,接收方将从中获取代码库并从该位置加载代码。(摘自@Nasir的回答)

序列化几乎就像对象使用的内存的一个愚蠢的内存转储,而编组存储关于自定义数据类型的信息。

在某种程度上,Serialization通过值传递的实现来执行封送,因为没有传递数据类型的信息,只是将原始形式传递到字节流。

如果流从一个操作系统到另一个操作系统,如果不同的操作系统有不同的表示相同数据的方法,序列化可能会有一些与大端序和小端序相关的问题。另一方面,编组非常适合在操作系统之间迁移,因为结果是更高级别的表示。

编组通常在相对紧密关联的进程之间进行;序列化不一定有这种期望。因此,当在进程之间编组数据时,例如,您可能希望仅发送一个引用到可能昂贵的数据以进行恢复,而使用序列化时,您可能希望保存所有数据,以便在反序列化时正确地重新创建对象。