加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – .NET GZipStream解压缩生成空流

发布时间:2020-12-15 17:39:59 所属栏目:百科 来源:网络整理
导读:我试图序列化和压缩一个 WPF FlowDocument ,然后反向解压缩字节数组并反序列化以重新创建FlowDocument – 使用.NET GZipStream 类.我正在跟踪MSDN上描述的示例,我有以下测试程序: var flowDocumentIn = new FlowDocument();flowDocumentIn.Blocks.Add(new P
我试图序列化和压缩一个 WPF FlowDocument,然后反向解压缩字节数组并反序列化以重新创建FlowDocument – 使用.NET GZipStream类.我正在跟踪MSDN上描述的示例,我有以下测试程序:
var flowDocumentIn = new FlowDocument();
flowDocumentIn.Blocks.Add(new Paragraph(new Run("Hello")));
Debug.WriteLine("Compress");
byte[] compressedData;
using (var uncompressed = new MemoryStream())
{
    XamlWriter.Save(flowDocumentIn,uncompressed);
    uncompressed.Position = 0;
    using (var compressed = new MemoryStream())
    using (var compressor = new GZipStream(compressed,CompressionMode.Compress))
    {
        Debug.WriteLine(" uncompressed.Length: " + uncompressed.Length);
        uncompressed.CopyTo(compressor);
        Debug.WriteLine(" compressed.Length: " + compressed.Length);
        compressedData = compressed.ToArray();
    }
}

Debug.WriteLine("Decompress");
FlowDocument flowDocumentOut;
using (var compressed = new MemoryStream(compressedData))
using (var uncompressed = new MemoryStream())
using (var decompressor = new GZipStream(compressed,CompressionMode.Decompress))
{
    Debug.WriteLine(" compressed.Length: " + compressed.Length);
    decompressor.CopyTo(uncompressed);
    Debug.WriteLine(" uncompressed.Length: " + uncompressed.Length);
    flowDocumentOut = (FlowDocument) XamlReader.Load(uncompressed);
}

Assert.AreEqual(flowDocumentIn,flowDocumentOut);

然而,我在XamlReader.Load行中收到异常,这是正常的,因为调试输出告诉未压缩的流具有零长度.

Compress
 uncompressed.Length: 123
 compressed.Length: 202
Decompress
 compressed.Length: 202
 uncompressed.Length: 0

为什么最终的未压缩流不包含原始的123个字节?

(请忽略“压缩”字节数组大于“未压缩”字节数组的事实 – 我通常会使用更大的流程文档)

解决方法

在从内存流获取压缩字节之前,需要关闭GZipStream.在这种情况下,由于使用所调用的Dispose处理关闭.
using (var compressed = new MemoryStream())
{
    using (var compressor = new GZipStream(compressed,CompressionMode.Compress))
    {
        uncompressed.CopyTo(compressor);
    }
    // Get the compressed bytes only after closing the GZipStream
    compressedBytes = compressed.ToArray();
}

这可以工作,甚至可以删除MemoryStream的使用,因为它将由GZipStream处理,除非您使用构造函数重载,允许您指定底层流应该保持打开状态.这意味着与代码一样,您调用ToArray处理的流,但这是允许的,因为这些字节仍然可用,这使得处理内存流有点奇怪,但如果你不这样做,FXCop会让你烦恼.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读