zoukankan      html  css  js  c++  java
  • 在内存流中对象的二进制序列化的问题

            翻看MSDN,关于对象序列化的示例最常见的都是在文件流中进行XML序列化,因为开发的需要,我必须要在内在流中将对象以二进制方式序列化,原以为很简单,copy一下示例改改就好了,原代码如下:

    public sealed class Serializer
    {
        
    private Serializer() { }

        
    public static string SerializeObject(object obj)
        
    {            
            IFormatter formatter 
    = new BinaryFormatter(); 
            
    string result = string.Empty;
            
    using (MemoryStream stream = new MemoryStream())
            
    {
                formatter.Serialize(stream, obj);

                
    byte[] byt = new byte[stream.Length];
                byt 
    = stream.ToArray();
                result 
    = Encoding.UTF8.GetString(byt, 0, byt.Length);
               
                stream.Flush();                
            }

            
    return result;
        }


        
    public static object DeserializeObject(string str)
        
    {         
            IFormatter formatter 
    = new BinaryFormatter();
            
    byte[] byt = Encoding.UTF8.GetBytes(str);
         
            
    object obj = null;
            
    using (Stream stream = new MemoryStream(byt, 0, byt.Length))
            
    {
                obj 
    = formatter.Deserialize(stream);
            }

            
    return obj;
        }

    }

            谁想到在单元测试的时候却是报忧不报喜啊,错误信息是这样:SerializerTest.SerializeObjectTest 引发异常:

    System.Runtime.Serialization.SerializationException: 二进制流“0”不包含有效的BinaryHeader。这可能是由于无效流,或由于在序列化和反序列化之间的对象版本更改。

            经过debug,发现SerializeObject方法中,"result = Encoding.UTF8.GetString(byt, 0, byt.Length);"此行代码运行过后,result的值居然是"\0\0\0……"一大串开头,难怪会报错的。
            此后我只是将BinaryFormatter换成XMlSerializer其他的不变,那倒是能正常得到结果的,可那不是我想要的啊,总是问题之关键在于将byte数组转为string时的字符串,所以接下来我先后用gb2312,ansi,unicode等Encoding来转换均无果,后来在Convert类中找到一个方法,修改后的代码如下:

    public sealed class Serializer
    {
        
    private Serializer() { }

        
    public static string SerializeObject(object obj)
        
    {
            IFormatter formatter 
    = new BinaryFormatter(); 
            
    string result = string.Empty;
            
    using (MemoryStream stream = new MemoryStream())
            
    {
                formatter.Serialize(stream, obj);

                
    byte[] byt = new byte[stream.Length];
                byt 
    = stream.ToArray();               
                
    //result = Encoding.UTF8.GetString(byt, 0, byt.Length);
                result = Convert.ToBase64String(byt);
                stream.Flush();                
            }

            
    return result;
        }


        
    public static object DeserializeObject(string str)
        
    {
            IFormatter formatter 
    = new BinaryFormatter();
            
    //byte[] byt = Encoding.UTF8.GetBytes(str);
            byte[] byt = Convert.FromBase64String(str);
            
    object obj = null;
            
    using (Stream stream = new MemoryStream(byt, 0, byt.Length))
            
    {
                obj 
    = formatter.Deserialize(stream);
            }

            
    return obj;
        }

    }

            再次单元测试通过了,说明修改有效,回头debug到“result = Convert.ToBase64String(byt);”,result的值开头没有"\0"了,都是字母,这才证明了序列化成功的原因。之后对基于64位的字符串转换应该多加关注,往往能起到令人惊喜的效果,本案总算是结案了。

  • 相关阅读:
    SQL2005的CTE
    分列顯示
    2005数据库结构显示
    十进制/十八进制的互转换(此方法应用于所有进制与10进制的转换)
    2005自动生成数据库的清空脚本
    阻塞分析
    通过在 Web 表单中维持对象的 ViewState (视图状态)
    cs文件调用aspx页面js函数
    Repeater绑定后格式化某字段
    Fireworks中制作炫光效果
  • 原文地址:https://www.cnblogs.com/BeanHsiang/p/901866.html
Copyright © 2011-2022 走看看