ISerializable 对象应该如何存储二进制数据?
Posted
技术标签:
【中文标题】ISerializable 对象应该如何存储二进制数据?【英文标题】:How should ISerializable object store binary data? 【发布时间】:2013-11-30 08:17:21 【问题描述】:我有一个引用类型,它在非托管内存中包含原始图像数据。很清楚如何使用SerializationInfo
存储元数据(宽度、高度),但是存储 BLOB 的最佳方式是什么?
我唯一能看到的是使用Convert.ToBase64String
,这需要大量的复制。有没有更直接的方法?
【问题讨论】:
【参考方案1】:更新:有更好的方法来处理这个问题!
您需要做的是查看传递给GetObjectData
的StreamingContext
,StreamingContext.State
属性可以告诉您正在发生什么样的序列化。如果您通过了Clone
或CrossAppDomain
状态,您可能能够重用您对非托管blob 拥有的现有句柄,只需将句柄指针传递给SerializationInfo
对象。
无论您选择什么,您都需要进行大量复制,但Convert.ToBase64String
是不必要的,您只需将您传递给Convert.ToBase64String
的托管byte[]
序列化就可以了。
我不知道byte[]
是否有任何特殊情况的效率,但是在传输过程中所有序列化get turned in to a byte stream。因此,通过在 Base64 中编码,您将要做的事情
-
读取非托管 blob 并将其转换为托管
byte[]
通过ToBase64String
将您的byte[]
转换为string
(由于编码,大小增加了4/3 倍)李>
将带有标签名称的编码字符串传递给SerializationInfo
将其余元数据及其相应标签传递到SerializationInfo
序列化程序获取所有标签+对象组合并将它们转换为字节流以传递到目标
反序列化器获取字节流并将其转回标签和对象的集合
您使用相同的标签名称返回您的string
您可以使用保存元数据的标签取回元数据。
通过FromBase64String
将string
转换回byte[]
将 byte[]
转换回非托管二进制 blob。
如果您从不编码为字符串,而只是将 byte[]
作为对象传递给 SerializationInfo
对象,则步骤几乎相同,只是没有那个 4/ 3 增加数据块的大小以将二进制数据编码为文本。
-
读取非托管 blob 并将其转换为托管
byte[]
将带有标签名称的byte[]
传递给SerializationInfo
将其余元数据及其相应标签传递到SerializationInfo
序列化程序获取所有标签+对象组合并将它们转换为字节流以传递到目标
反序列化器获取字节流并将其转回标签和对象的集合
您使用相同的标签名称返回您的byte[]
您可以使用保存元数据的标签取回元数据。
将 byte[]
转换回非托管二进制 blob。
所以我猜想“优化”是作为byte[]
传输的,其好处是不会增加您必须传输到去耳化器的数据量。
【讨论】:
这很不幸。byte[]
是为了提高效率而特例,你知道吗,还是将元数据存储在每个单独的元素后面作为单独的项目?有没有其他简单的方法可以在程序运行之间存储一些对象?
我添加了一个广泛的更新来回答您问题的第一部分。对于您的第二个问题,这取决于您的目标是什么:最简单的实现、最小的大小、人类可读、跨平台支持、跨 .NET 框架版本支持? (如果最后一个答案是“否”,那么BinaryFormmater
可能是“最简单”的解决方案)?
@BenVoigt 我之前没想过,是的,任何传入AddValue(
的this overload 的对象可以进行优化.将会发生的事情是它将在传入的对象上调用GetObjectData()
,并且嵌套的searlizer会执行它选择做的任何优化(因此由Array
的seralizer来确定是否有任何优化)
您还应该考虑的一件事,如果您序列化为byte[]
,然后将您的序列化流传递给XMLSearalizer
,它会将byte[]
文件编码为十六进制,这将在大小上比 Base64 编码效率低得多,所以也许 Base64 会更好。
这就是我所怀疑的。虽然我担心它可能会更糟,例如逗号分隔的十进制编码值列表。以上是关于ISerializable 对象应该如何存储二进制数据?的主要内容,如果未能解决你的问题,请参考以下文章
Serializable 指示一个类可以序列化;ICloneable支持克隆,即用与现有实例相同的值创建类的新实例(接口);ISerializable允许对象控制其自己的序列化和反序列化过程(接口)(
将 ISerializable 与 DataContractSerializer 一起使用时,如何阻止序列化程序输出类型信息?