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)
感谢你们俩!
我下载了你的例子并在那里进行了一些挖掘。请参阅下面对您的项目的更改:
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;
}
}
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)