为什么压缩字节大于字节?

时间:2018-08-09 04:35:40

标签: c# file

在下面的代码中,我注意到compressedBytes的值为147,大于bytes 100。

我认为compressedBytes应该少一些。请提出原因?

byte[] compressedBytes;
        byte[] bytes = File.ReadAllBytes(filename); //byte[100]
        using (var outStream = new MemoryStream())
        {
            using (var archive = new ZipArchive(outStream, ZipArchiveMode.Create, true))
            {
                var fileInArchive = archive.CreateEntry("test.txt", CompressionLevel.Optimal);
                using (var entryStream = fileInArchive.Open())
                using (var fileToCompressStream = File.Open(filename, FileMode.Open))
                {
                    var X = fileToCompressStream.Length; //100
                    fileToCompressStream.CopyTo(entryStream);
                }
            }
            compressedBytes = outStream.ToArray(); //byte[147]
        }

1 个答案:

答案 0 :(得分:4)

非常简化,想象一下ZIP文件的工作方式如下:

  • 它有一个索引,指出其中包含的文件名以及在哪里可以找到它们
  • 它通过说出每个字节重复多少次来压缩每个文件

因此,如果您的文件layers.pic包含:0 0 0 0 0 0 0 0 50 50 50 50 50 50 50 50 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 ,您可以改为说:“ layers.pic,紧接在索引之后,分别为8x0、8x50、16x100”,它会更短。但是,假设文件是​​否只有0 17 39;那么“压缩”实际上是文件(1x0 1x17 1x39)的两倍,并且您仍然需要浪费额外的空间告诉索引它的原始名称以及在哪里找到它。即使我们认为压缩不值得,并且将文件原样存储到存档中,我们仍然会增加文件大小,因为我们需要在索引中放入一些内容。

(ZIP存档比这要复杂一些;但是基本原理非常接近-包括如果条目最终变大则不压缩的选项。)

编辑:如果您检出Wikipedia page,则可以发现每个文件条目的标头至少为30个字节加上文件名大小;中心索引以扩展的形式再次重复该信息;那么至少有20个字节的EOCD。您的文件名为test.txt,占8个字节,因此仅元数据已至少占据(30 + 8)+(46 + 8)+ 20 = 112字节,而压缩数据本身却不占空间(因此占用了最多35个字节)。