为啥压缩然后未压缩不同长度的流

Posted

技术标签:

【中文标题】为啥压缩然后未压缩不同长度的流【英文标题】:Why is compressed then uncompressed stream of different length为什么压缩然后未压缩不同长度的流 【发布时间】:2011-05-12 07:02:45 【问题描述】:

我正在使用 SevenZipSharp 库来压缩然后解压缩包含简单序列化对象的 MemoryStream。但是,压缩流和解压缩流的长度不同。

从下面运行的代码中我得到

输入长度:174 输出长度:338

(SevenZipSharp dll 包含在参考中,7z.dll 包含在项目输出中)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace DataTransmission 
class Program 
    static void Main(string[] args)
    

        SevenZip.SevenZipCompressor compressor = new SevenZip.SevenZipCompressor();
        //compressor.CompressionMethod = SevenZip.CompressionMethod.Lzma2;
        //compressor.CompressionLevel = SevenZip.CompressionLevel.Normal;

        MemoryStream inputStream = new MemoryStream();

        Person me = new Person("John", "Smith");
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(inputStream, me);

        Int32 inputStreamLength = (Int32)inputStream.Length;

        MemoryStream outputStream = new MemoryStream();

        compressor.CompressStream(inputStream, outputStream);
        SevenZip.SevenZipExtractor decompressor = new SevenZip.SevenZipExtractor(outputStream);
        decompressor.ExtractFile(0, outputStream);
        Int32 outputStreamLength = (Int32)outputStream.Length;


        Console.WriteLine("Input length: 0", inputStreamLength);
        Console.WriteLine("Output length: 0", outputStreamLength);

        Console.ReadLine();
    


[Serializable]
public class Person 
    public string firstName;
    public string lastName;

    public Person(string fname, string lname) 
        firstName = fname;
        lastName = lname;
    



谁能帮我解释为什么会这样?

谢谢,

【问题讨论】:

对压缩和解压缩数据使用单独的流。您的 outputStream 可能包含 Compressed + Decompressed。 【参考方案1】:

尽管已经包含数据,但您已解压缩为 outputStream。您应该使用 new MemoryStream 作为输出。

(事实上,这很奇怪,因为解压缩器正在读取 from outputStream 并写入 to outputStream。坏主意。使用两个不同的流。)

您还应该在写入每个流之后以及在其他内容想要读取它之前回退每个流,例如与

inputStream.Position = 0;

在这种情况下,SevenZipLib 可能会为您执行此操作,但通常如果您希望从流的开头开始执行某些操作,则应适当地重置它。


我刚刚对您的代码进行了以下更改,此时输入和输出的长度相同:

MemoryStream targetStream = new MemoryStream();
decompressor.ExtractFile(0, targetStream);
Int32 outputStreamLength = (Int32)targetStream.Length;

正如我所说,您也应该进行适当的其他更改。

【讨论】:

太棒了!感谢您的帮助,您的修改实际上是问题所在,我现在将按照您的建议进行其他更改。再次感谢您的及时回复!【参考方案2】:

但是,压缩和解压缩的流长度不同

这就是压缩的全部目的......


看这段代码:

  SevenZip.SevenZipExtractor decompressor = 
       new SevenZip.SevenZipExtractor(outputStream);
  decompressor.ExtractFile(0, outputStream);

你正在解压缩 outputStream outputStream。它可能会因更大的数据而失败。进行更改以使其读取

  SevenZip.SevenZipExtractor decompressor = 
      new SevenZip.SevenZipExtractor(compressedStream);
  decompressor.ExtractFile(0, outputStream);

【讨论】:

看他的代码应该就明白他的意思了。此外,问题标题还指出,问题是 original -> compress -> uncompress -> neworiginalnew 具有不同的长度。 @Daniel:是的,我对第一段做出了反应。

以上是关于为啥压缩然后未压缩不同长度的流的主要内容,如果未能解决你的问题,请参考以下文章

请问为啥同一个压缩文件显示的大小却不同呢?

myisam压缩(前缀压缩)索引

为啥我的产品->存档因“非法尝试在不同上下文中的对象之间建立关系”压缩类型“而失败?

zlib gunzip解压缩每个在同一文件上运行的不同缓冲区大小

GZIP压缩和解压

哈夫曼编码压缩解压缩实现&不同类型文件压缩比的测试