【问题标题】:Is it practical to concatenate GZipStreams?连接 GZipStreams 是否可行?
【发布时间】:2012-11-30 09:34:12
【问题描述】:

我构想了将任意数量的小文本文件合并为 1 个具有 GZipStream 类的单个 zip 文件的想法。我花了几个晚上让它工作,但结果是最终的 zip 文件最终比文本文件连接在一起时更大。我隐约知道霍夫曼编码是如何工作的,所以我不知道这样做是否实用,或者是否有更好的选择。最终,我想要一个外部排序索引文件来映射每个 blob 以便快速访问。你怎么看?

// keep track of index current position 
long indexByteOffset = 0;
// in reality the blobs vary in size from 1k to 300k bytes
string[] originalData = { "data blob1", "data blob2", "data blob3", "data blob4" /* etc etc etc */};
// merged compressed file
BinaryWriter zipWriter = new BinaryWriter(File.Create(@"c:\temp\merged.gz"));
// keep track of begining position and size of each blob
StreamWriter indexWriter = new StreamWriter(File.Create(@"c:\temp\index.txt")); 
foreach(var blob in originalData){
    using(MemoryStream ms = new MemoryStream()){
        using(GZipStream zipper = new GZipStream(ms, CompressionMode.Compress)){
            Encoding utf8Encoder = new UTF8Encoding();
            byte[] encodeBuffer = utf8Encoder.GetBytes(blob);
            zipper.Write(encodeBuffer, 0, encodeBuffer.Length);
        }
        byte[] compressedData = ms.ToArray();
        zipWriter.Write(compressedData);
        zipWriter.Seek(0, SeekOrigin.End);
        indexWriter.WriteLine(indexByteOffset + '\t' + (indexByteOffset + compressedData.Length));
        indexByteOffset += compressedData.Length;
    }
}

【问题讨论】:

    标签: c# compression gzipstream


    【解决方案1】:

    不同的数据可以有不同的压缩效果。小数据通常不值得尝试压缩。一种常见的方法是允许“它是否被压缩?”标志 - 进行推测压缩,但如果它更大,则存储原始压缩。该信息可以包含在索引中。不过,就个人而言,我可能会倾向于使用单个文件 - 一个 .zip,或者只是将每个片段的长度包含为一个 4 字节块(或者可能是一个“varint”)before each - 然后寻找第 n 个片段只是“读取长度前缀,解码为 int,寻找那么多字节,重复”的情况。您也可以保留其中的一部分用于“是否已压缩”。

    但至于“是否值得压缩”:这取决于您的数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-02
      • 2019-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-20
      • 2018-08-18
      • 2015-06-04
      相关资源
      最近更新 更多