C#自定义序列化/反序列化与DeflateStreams一起使用

ves*_*esz 5 c# serialization deflatestream deserialization

我正在尝试对对象进行自定义序列化/反序列化,以及使用DeflateStreams压缩/解压缩序列化数据.我最初为更复杂的对象做了这个,但是把它剪下来试图找出问题,然而它变得更加令人费解,因为它仍然存在.这是要序列化/反序列化的类:

[Serializable]
    public class RandomObject : ISerializable
    {
        public String Name { get; set; }
        public String SavePath { get; set; }

        public RandomObject()
        {
        }

        public RandomObject(String name, String savepath)
        {
            Name = name;
            SavePath = savepath;
        }

        public RandomObject(SerializationInfo info, StreamingContext context)
            : this(info.GetString("name"), info.GetString("savepath"))
        {
        }
        [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("name", Name);
            info.AddValue("savepath", SavePath);
        }
    }
Run Code Online (Sandbox Code Playgroud)

这里是应该序列化它的代码(似乎工作):

BinaryFormatter bf = new BinaryFormatter();
            using (MemoryStream ms = new MemoryStream())
            {
                bf.Serialize(ms, profile);
                using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Compress))
                {
                    try
                    {
                        using (FileStream fs = File.Create(path))
                        {
                            ds.Flush();
                            Miscellaneous.CopyStream(ds.BaseStream, fs);
                            fs.Flush();
                            fs.Close();
                        }
                    }
                    catch (IOException e)
                    {
                        MessageBox.Show(e.Message);
                        success = false;
                    }
                    ds.Close();
                }
                ms.Close();
            }
Run Code Online (Sandbox Code Playgroud)

这是反序列化:

RandomObject profile = null;
                using (FileStream fs = File.OpenRead(path))
                {
                    using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Decompress))
                    {
                        BinaryFormatter bf = new BinaryFormatter();
                        ds.Flush();

                        using (MemoryStream ms = new MemoryStream())
                        {
                            Miscellaneous.CopyStream(ds.BaseStream, ms);
                            profile = bf.Deserialize(ms) as RandomObject;
                            profile.SavePath = path;
                            ms.Close();
                        }
                        ds.Close();
                    }
                    fs.Close();
                }
Run Code Online (Sandbox Code Playgroud)

现在,问题.反序列化抛出一个SerializationException,消息{"没有对象的映射'201326592'."}我不知道如何排除故障或找出导致问题的确切原因.当我在同一个MemoryStream上运行BinaryFormatter的Serialize和Deserialize方法时,非常基本的序列化工作.

我尝试从两种方法中删除DeflateStream的东西,但它仍然是同样的问题.当我查看MSDN和其他地方的示例时,看起来我正在做的恰到好处,并且搜索异常消息并没有给出任何有意义的结果(或者我可能只是在搜索时很糟糕).

PS.正如你所看到的,我使用Miscellaneous.CopyStream(src,dest)这是一个基本的流复制器,因为我无法让src.CopyTo(dest)工作,所以任何关于它的提示也是受欢迎的.

以下是整个VS2010项目的链接,如果您想更仔细地查看它:http: //www.diredumplings.com/SerializationTesting.zip

更新:

The_Smallest:我尝试使用你在序列化中发布的Compress方法:

BinaryFormatter bf = new BinaryFormatter();
            using (MemoryStream stream = new MemoryStream())
            {
                bf.Serialize(stream, profile);

                byte[] array = Compress(stream);

                using (MemoryStream ms = new MemoryStream(array))
                {
                    using (FileStream fs = File.Create(path))
                    {
                        ms.WriteTo(fs);
                        fs.Flush();
                    }
                }
            }
Run Code Online (Sandbox Code Playgroud)

但是,它似乎给了我与之前srcStream.CopyTo(destStream)相同的问题,即它似乎没有被写入流.当我尝试将其保存到磁盘时,结果是一个0 kb的文件.有任何想法吗?

Pieter:我从反序列化方法中删除了MemoryStream,它似乎具有与以前相同的功能.但是,我不确定如何按照您的建议实现序列化.这是你的想法吗?

BinaryFormatter bf = new BinaryFormatter();

            using (FileStream fs = File.Create(path))
            {
                using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Compress))
                {
                    bf.Serialize(ds, profile);
                    fs.Flush();
                    ds.Close();
                }
                fs.Close();
            }
Run Code Online (Sandbox Code Playgroud)

感谢你们俩!

The*_*est 1

我下载了你的例子并在那里进行了一些挖掘。请参阅下面对您的项目的更改:

  1. 替换LoadFromFileLoader.cs中的
private static RandomObject LoadFromFile(string path)
{
  try
  {
    var bf = new BinaryFormatter();
    using (var fileStream = File.OpenRead(path))
    using (var decompressed = new MemoryStream())
    {
      using (var deflateStream = new DeflateStream(fileStream, CompressionMode.Decompress))
        deflateStream.CopyTo(decompressed);

      decompressed.Seek(0, SeekOrigin.Begin);
      var profile = (RandomObject)bf.Deserialize(decompressed);
      profile.SavePath = path;
      return profile;
    }
  }
  catch (IOException e)
  {
    MessageBox.Show(e.Message);
    return null;
  }
}

  1. 在Saver.cs中替换Save如下:
public static bool Save(RandomObject profile, String path)
{
   try
   {
      var bf = new BinaryFormatter();
      using (var uncompressed = new MemoryStream())
      using (var fileStream = File.Create(path))
      {
         bf.Serialize(uncompressed, profile);
         uncompressed.Seek(0, SeekOrigin.Begin);

         using (var deflateStream = new DeflateStream(fileStream, CompressionMode.Compress))
           uncompressed.CopyTo(deflateStream);
      }
      return true;
    }
    catch (IOException e)
    {
       MessageBox.Show(e.Message);
       return false;
    }
}
Run Code Online (Sandbox Code Playgroud)