Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用BinaryReader和BinaryWriter创建自己的二进制序列化程序?_C#_.net - Fatal编程技术网

C# 如何使用BinaryReader和BinaryWriter创建自己的二进制序列化程序?

C# 如何使用BinaryReader和BinaryWriter创建自己的二进制序列化程序?,c#,.net,C#,.net,我基本上想创建自己的二进制序列化类,这有点像BinaryFormatter类正在做的事情。如何使用BinaryReader和BinaryWriter类来完成此任务。 我不想要任何代码,只想要一个想法。 谢谢 PS:请不要告诉我使用BinaryFormatter最终,您需要选择每种类型的策略,然后切换到每种类型;BinaryWriter有编写Int32、String等的方法,所以一个基本的方法是使用大量反射和切换te FieldInfo/PropertyInfo的有效类型的GetTypeCode

我基本上想创建自己的二进制序列化类,这有点像
BinaryFormatter
类正在做的事情。如何使用
BinaryReader
BinaryWriter
类来完成此任务。 我不想要任何代码,只想要一个想法。 谢谢
PS:请不要告诉我使用BinaryFormatter

最终,您需要选择每种类型的策略,然后切换到每种类型;BinaryWriter有编写Int32、String等的方法,所以一个基本的方法是使用大量反射和切换te FieldInfo/PropertyInfo的有效类型的GetTypeCode

就我个人而言,这样做之后,我实际上会避免使用BinaryReader/Writer,而直接使用流(使用浮动字节[]缓冲区进行工作)

为了获得更高的级别,您可以通过使用元编程来预编译每个成员或每个类型的内容来减少反射量

其他需要考虑的事项:

  • 标记每个数据字段需要哪些标题数据(如果有)
  • 如何打包子对象/继承/列表

这两个问题都很容易解决,当然要了解如何实现序列化,您可以查看的c#源代码。可以找到源代码。该代码也可以在windowsmobile、silverlight下运行。

我建议使用类似的工具,您可以使用类上的属性设置该工具,它将处理所有二进制序列化/反序列化

我最近不得不对其进行扩展,以便在一个具有更紧凑格式的泛型类中提供客户序列化支持。就像Marc提到的那样,只需编写处理序列化/反序列化特定类型的代码,然后切换运行您要编写的特定对象类型的代码

下面是我为允许在泛型类中序列化数据而采取的方法的基本概述:

MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);

writer.Write(_size);
for (int i = 0; i < _size; i++)
    _indices[i].AddToStream(writer);

if (_serializeDataToStream == null)
    _serializeDataToStream = (Action<BinaryWriter, int, T[]>)GetTypeSpecificSerializationMethod();

_serializeDataToStream(writer, _size, _data);

return stream.ToArray();
MemoryStream stream=newmemoryStream();
BinaryWriter=新的BinaryWriter(流);
writer.Write(_size);
对于(int i=0;i<\u size;i++)
_索引[i].AddToStream(编写器);
if(_serializedDataToStream==null)
_serializeDataToStream=(操作)GetTypeSpecificSerializationMethod();
_序列化DataToStream(写入程序、\u大小、\u数据);
返回流ToArray();
这是在泛型类中,\ u serializedDataToStream是静态的,因此每个泛型类型只需查找一次

private Delegate GetTypeSpecificSerializationMethod()
{
    if (typeof(T) == typeof(double))
    {
        MethodInfo method = this.GetType().GetMethod("SerializeDouble", BindingFlags.Static | BindingFlags.NonPublic);
        return Delegate.CreateDelegate(typeof(Action<BinaryWriter, int, T[]>), method);
    }
    else if (typeof(T) == typeof(ushort))
    {
    ...


private static void SerializeDouble(BinaryWriter writer, int size, double[] data)
{
    for (int i = 0; i < size; i++)
    {
        writer.Write(data[i]);
    }
}
private委托GetTypeSpecificSerializationMethod()
{
如果(类型(T)=类型(双))
{
MethodInfo method=this.GetType().GetMethod(“SerializeDouble”,BindingFlags.Static | BindingFlags.NonPublic);
返回Delegate.CreateDelegate(typeof(Action),method);
}
否则如果(typeof(T)=typeof(ushort))
{
...
私有静态void序列化double(BinaryWriter编写器,int size,double[]数据)
{
对于(int i=0;i
如果你不说BinaryFormatter有什么问题,这是不可能准确回答的。你的版本到底需要如何更好地工作?我这样做是作为一个学习练习。BinaryFormatter一点问题都没有+BinaryFormatter在CF上不受支持,我希望在这两方面都使用一些轻量级的格式化程序。@Hans oh不明白我的意思开始:)我可以整个下午都在讨论这个问题……您可能还想看看现有的公共二进制序列化格式;有很多可供选择的格式。我以前创建了自己的“更好”二进制序列化程序,用于截取简单的案例(布尔、int等)并使用简单的方案或未编码的方式存储数据。这更好,因为它使用的空间比编码的二进制数据少得多,在这种情况下,简单的情况代表了绝大多数数据。为什么要避免使用
BinaryReader
BinaryWriter
?我(大部分)使用过它们好的效果。我承认有时会有一些烦恼,但总的来说我更喜欢它们。你认为使用
byte[]
缓冲区有什么好处?@Jim-在我的例子中,数据格式与BinaryReader/Writer会选择的格式不完全匹配(protobuf使用可变长度编码),并且涉及大量的二进制杂耍;最好直接将其写入一个临时缓冲区,并尽量减少读/写调用的数量。请注意,缓冲区满时会刷新-我不会在内存中组装整个内容(这会产生很大的内存开销).但主要是第一个原因:它不会给我提供任何东西。是的,可变长度编码有点痛苦。谢谢你提供的信息。