【发布时间】:2014-01-19 23:21:10
【问题描述】:
我正在创建一个程序,它必须在客户端和服务器之间有效地发送数据。为了清楚地组织数据包,我使用了序列化。但是,当我序列化这些数据包时,数据会变得不必要地大。我将解释我在做什么,以便您了解我需要什么。
我的数据包类是这样工作的。我有一个 Packet 对象:
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public class Packet
{
public static byte[] Serialize(Object o)
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, o);
return ms.ToArray();
}
public static Object Deserialize(byte[] bt)
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
ms.Write(bt, 0, bt.Length);
ms.Position = 0;
object obj = bf.Deserialize(ms);
ms.Close();
return obj;
}
}
然后我可以创建其他继承自 Packet 类的类,这是一个示例:
using System;
[Serializable]
public class PacketUserInfo : Packet
{
public string Name;
public int Age;
}
那么,就很简单了,把它放到一个字节数组中发送出去(当然上面的数据包只是一个例子)。但是,结果数组的大小至少比我使用 BinaryWriter 并手动写入信息时大 10 倍。
为什么序列化的数据这么大?有没有什么办法可以减少它,同时仍然保持一切都以包作为自己的类来组织?
注意:我只是想序列化这样的简单属性,没什么特别的。
【问题讨论】:
-
虽然我无法为您提供这种行为的确切原因,但我想推荐一个序列化库,我与人合着了 Migrant - github.com/antmicro/Migrant 。它允许以很少的结果数据开销和几乎没有样板代码来序列化您的类。事实上,对于简单的情况,它不需要任何代码。它还提供了诸如具有循环的对象的复杂图等功能。
-
我会看看它...如果看起来切换到它不需要太多工作,我会尝试它。谢谢。
-
BinaryFormatter不是机器到机器搜索的好选择,如果两台机器具有不同的核心 .NET DLL 的 DLL 版本(假设一台机器尚未运行它的 Windows 更新,当一个修补程序到.NET 出来)您的数据将无法解串。 (我什至不建议将它保存到同一台机器的磁盘,唯一不用担心解串问题的地方是用于同一台机器上的 IPC 通信) -
我明白了,那么在将数据保存在这些整洁的类中的同时,我还能如何发送数据?
-
正如我所说,在大多数情况下,Migrant 不需要任何额外的代码。请记住,Migrant 针对大部分数据进行了优化,针对小类的进一步优化尚未到来。例如,如果您只是序列化这样一个小数据包的一部分,它可能会比二进制格式化程序占用更多的空间。如果您需要任何帮助,请写信至 github 上提供的电子邮件,我们会尽快回复。
标签: c# sockets serialization