【问题标题】:C# Object Binary SerializationC# 对象二进制序列化
【发布时间】:2010-12-17 11:15:32
【问题描述】:

我想对一个对象进行二进制序列化,并将结果保存在数据库中。

Person person = new Person();
person.Name = "something";

MemoryStream memorystream = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(memorystream, person);

如何将内存流转换为字符串类型以保存在数据库中,然后才能反序列化对象?

【问题讨论】:

    标签: c# string serialization binaryformatter


    【解决方案1】:

    真正要求的是一种将任意二进制数据表示为文本然后再次将其转换回来的安全方法。它存储序列化对象的事实是无关紧要的。

    答案几乎是使用 Base 64(例如 Convert.ToBase64StringConvert.FromBase64String)。 不要使用Encoding.UTF8.GetString或类似的东西 - 你的二进制数据是编码的文本数据,不应该被这样对待。

    但是,您的数据库是否没有二进制数据的数据类型?检查 BLOB、IMAGE 和 BINARY 类型...

    【讨论】:

    • 字节到字符串 --- 需要一些编码。
    • @loneshark99:我完全不明白你的评论。如果这是任意二进制数据 - 而不是编码文本 - 那么使用 Encoding 将是 错误 方法。
    • 我正在学习,但我想知道为什么 Encoding 不是正确的方法而 ToBase64String 是。
    • @loneshark99:因为Encoding 是为本质上是文本的数据而设计的——它将文本转换为二进制数据,而 base64 和十六进制旨在将固有的二进制任意数据表示为文本而不会丢失信息.
    • 谢谢你说得通!我总是对编码感到困惑。谢谢!!
    【解决方案2】:

    这是示例。 TData 必须标记为 [Serializable] 并且所有字段类型也必须标记。

        private static TData DeserializeFromString<TData>(string settings)
        {
            byte[] b = Convert.FromBase64String(settings);
            using (var stream = new MemoryStream(b))
            {
                var formatter = new BinaryFormatter();
                stream.Seek(0, SeekOrigin.Begin);
                return (TData)formatter.Deserialize(stream);
            }
        }
    
        private static string SerializeToString<TData>(TData settings)
        {
            using (var stream = new MemoryStream())
            {
                var formatter = new BinaryFormatter();
                formatter.Serialize(stream, settings);
                stream.Flush();
                stream.Position = 0;
                return Convert.ToBase64String(stream.ToArray());
            }
        }
    

    【讨论】:

      【解决方案3】:
      //-------write to database-------------------------
      Person person = new Person();
      person.name = "Firstnm  Lastnm";
      MemoryStream memorystream = new MemoryStream(); 
      BinaryFormatter bf = new BinaryFormatter();
      bf.Serialize(memorystream, person);
      byte[] yourBytesToDb = memorystream.ToArray();
      //here you write yourBytesToDb to database
      
      
      //----------read from database---------------------
      //here you read from database binary data into yourBytesFromDb
      MemoryStream memorystreamd = new MemoryStream(yourBytesFromDb);
      BinaryFormatter bfd = new BinaryFormatter();
      Person deserializedperson = bfd.Deserialize(memorystreamd) as Person;
      

      【讨论】:

      • MemoryStream周围应该有一个using
      【解决方案4】:

      我用过这样的东西

      MemoryStream memoryStream = new MemoryStream();
      BinaryFormatter binaryFormatter = new BinaryFormatter();
      binaryFormatter.Serialize(memoryStream, Person);
      memoryStream.Flush();
      memoryStream.Position = 0;
      string value = Convert.ToBase64String(memoryStream.ToArray());
      

      【讨论】:

      • 您不需要在调用 ToArray 之前回退 MemoryStream - 无论当前位置如何,它都会返回整个流的数据。同样,Flush 不会在 MemoryStream 上做任何事情,尽管它对一般流来说是个好主意。
      【解决方案5】:

      基本上,不要将数据作为字符串保存到数据库中,有blob字段可用于存储二进制数据。

      如果您确实需要将数据作为字符串,则需要使用 base64 编码将 byte[] 转换为字符串,并使用解码从字符串中获取 byte[]。

      【讨论】:

        【解决方案6】:

        您是否没有考虑将内存流转换为 base64hex 字符串以放入数据库中?

         byte[] mStream = memorystream.ToArray();
         string sConvertdHex = System.Convert.ToBase64String(mStream)
        

        然后您可以将内容 sConvertdHex 转储到数据库中。要反序列化它,您需要执行相反的操作

         byte[] mData = System.Convert.FromBase64String(...)
        

        然后将 mData 反序列化回您的对象。

        【讨论】:

          猜你喜欢
          • 2011-10-18
          • 2014-01-30
          • 1970-01-01
          • 2016-07-27
          • 1970-01-01
          • 2017-10-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多