如何分阶段创建zip文件?

时间:2015-02-15 22:43:28

标签: c# zip gzip

我正在以下列方式将数据写入ZIP文件:

    private static void ZipStringToFile(string value)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            using (GZipStream compressedzipStream = new GZipStream(ms, CompressionMode.Compress, true))
            {
                byte[] queryData = _encUtf8.GetBytes(value);
                compressedzipStream.Write(queryData, 0, queryData.Length);
                compressedzipStream.Write(_dataEndOfLine, 0, _dataEndOfLine.Length);
            }
            using (FileStream outfile = new FileStream("TestZip.zip", FileMode.Append))
            {
                byte[] buffer2 = new byte[ms.Length];
                ms.Seek(0, SeekOrigin.Begin);
                ms.Read(buffer2, 0, buffer2.Length);
                outfile.Write(buffer2, 0, buffer2.Length);
            }
        }
    }

效果很好。但是,如果我再次使用相同的方法:

        ZipStringToFile("String #1");
        ZipStringToFile("\r\n");
        ZipStringToFile("String #2");

我有更大的zip文件(因此我认为文件包含两个字符串),但在使用“TotalCommander”嵌入式存档器解压缩后,我只看到“字符串#2”。

我认为zip文件本身的结构不允许“附加”,所以我的方法中有一些主要的错误。

我是否应该首先将所有内容序列化到文件中并压缩到最后?或者有正确的方法将数据附加到zip存档?

感谢。

2 个答案:

答案 0 :(得分:1)

您正在使用“zip”一词。 gzip不是拉链。 gzip是单个流的压缩数据格式。 zip是多个文件的存档格式。你正在生成gzip流。

可以连接gzip流来创建更大,更有效的gzip流。兼容的gzip解码器应该从连接流中提供所有数据。所以要么你没有正确地连接它们,要么你没有正确地将连接结果传递给“TotalCommander”,或者“TotalCommander”不是兼容的gzip解码器。

  

我是否应该首先将所有内容序列化为文件和zip   在结束?

总的来说,是的,你应该。原因是如果只提供gzip小字符串,你会得到糟糕的压缩。为了获得良好的压缩效果,您需要为gzip提供更多可用的数据。

答案 1 :(得分:0)

如果您使用的是ASP.NET ZipArchive库,我的建议是尝试:

  1. 检查拉链是否存在
  2. 如果存在,请将其打开。
  3. 使用GetEntry函数打开现有存档条目
  4. 打开()流的条目,然后将新数据写入流
  5. 将存档保存回磁盘。
  6. 否则,您可能每次都会覆盖现有存档。