【问题标题】:Binary Serialization in c#c#中的二进制序列化
【发布时间】:2019-11-25 13:49:47
【问题描述】:

我正在尝试使用 C# 中的二进制序列化来序列化类对象。我已经尝试过,并且在我所看到的所有示例中,我发现序列化的数据总是进入一个文件。

就我而言,我必须将序列化数据存储在 SQL 中。以下是我创建的方法的示例。

//Serializing the List
public void Serialize(Employees emps, String filename)
{
    //Create the stream to add object into it.
    System.IO.Stream ms = File.OpenWrite(filename); 
    //Format the object as Binary

    BinaryFormatter formatter = new BinaryFormatter();
    //It serialize the employee object
    formatter.Serialize(ms, emps);
    ms.Flush();
    ms.Close();
    ms.Dispose();
}

如何直接在字符串变量中获取序列化数据?我不想使用文件。

请帮忙。

【问题讨论】:

  • 二进制序列化和字符串不兼容。你为什么要把它放在一个字符串中?因为那时你应该对它进行base64编码。或者,只需使用 VARBINARY 列。
  • 你不能!!!对二进制数据使用字符串方法会损坏数据。 c#要求使用编码将二进制数据转换为字符串,编码会改变或删除不符合编码的字节。从示例中使用 UTF8 编码将消除字节 0x80。
  • 这一点我怎么强调都不为过:BinaryFormatter 不是适用于这种情况;事实上,在大多数情况下,您应该认为 BinaryFormatter 已过时且已弃用 - 有 很多 已知不使用它的原因,并且已经进行了许多尝试以正式弃用它。这不是“这会伤害我吗?”的情况。 - 是“when”的情况。如果您只想存储数据,还有 很多 其他序列化程序 - 二进制和基于文本的,它们没有 BinaryFormatter 那样的巨大红色警告标志。如果您愿意,很乐意提供建议。

标签: c# serialization binary binaryformatter


【解决方案1】:

C# 中将字节数组表示为字符串的最简单方法是使用base64 编码。下面的示例显示了如何在您的代码中实现这一点。

        public void Serialize(Employees emps, String filename)
        {
            //Create the stream to add object into it.
            MemoryStream ms = new MemoryStream();

            //Format the object as Binary

            BinaryFormatter formatter = new BinaryFormatter();
            //It serialize the employee object
            formatter.Serialize(ms, emps);

            // Your employees object serialised and converted to a string.
            string encodedObject = Convert.ToBase64String(ms.ToArray());

            ms.Close();
        }

这将创建字符串encodedObject。要从字符串中检索字节数组和序列化对象,您将使用以下代码。

            BinaryFormatter bf = new BinaryFormatter();

            // Decode the string back to a byte array
            byte[] decodedObject = Convert.FromBase64String(encodedObject);

            // Create a memory stream and pass in the decoded byte array as the parameter
            MemoryStream memoryStream = new MemoryStream(decodedObject);

            // Deserialise byte array back to employees object.
            Employees employees = bf.Deserialize(memoryStream);

【讨论】:

  • 为什么是“ms.Flush(); ms.Close();”?可以直接调用“ms.Dispose();”没有任何问题。
  • 我只是复制并粘贴了他的代码然后进行了更改,你是正确的 Flush 方法在内存流中什么都不做,但是 dispose 方法也是多余的。调用 close 将关闭流以进行读写,但是底层缓冲区仍然可用。 docs.microsoft.com/en-us/dotnet/api/…
  • 对不起,我刚刚读了一些书,结果发现 Dispose 和 Close 可以互换使用。
  • 对于 .Net 5,BinaryFormatter 序列化已过时,不应使用。
【解决方案2】:

只需使用MemoryStream ms = new MemoryStream() 而不是您的文件流。 您可以在序列化后通过调用ms.ToArray() 提取用于存储到SQL 的字节[]。

并且不要忘记将您的 Stream 放入 using-Statement 中,以保证正确处置分配的资源。

【讨论】:

    猜你喜欢
    • 2011-06-08
    • 2012-06-15
    • 2016-07-27
    • 2017-10-18
    • 1970-01-01
    • 2010-12-17
    • 2015-09-17
    • 2016-02-21
    • 1970-01-01
    相关资源
    最近更新 更多