我构思了这个想法,用GZipStream类将任意数量的小文本文件合并为1个单个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;
}
}
答案 0 :(得分:1)
不同的数据可以压缩效果不同。小数据通常不值得尝试压缩。一种常见的方法是允许“压缩它吗?” flag - 做一个推测压缩,但如果它更大,则存储原始。该信息可以包含在索引中。但就个人而言,我可能会想要一个单独的文件 - 一个.zip,或者只是将每个片段的长度包含为一个4字节的块(或者可能是一个“varint”)之前 each - 然后寻找第n个片段只是“读取长度前缀,解码为int,寻找那么多字节,重复”的情况。您也可以为“压缩它”保留一点。
但至于“值得压缩”:这取决于你的数据。