3

我想用 C# 创建一个包含将近 8 GB 数据的 zip 文件。我正在使用以下代码:

using (var zipStream = new ZipOutputStream(System.IO.File.Create(outPath)))
{
    zipStream.SetLevel(9); // 0-9, 9 being the highest level of compression

    var buffer = new byte[1024*1024];

    foreach (var file in filenames)
    {
        var entry = new ZipEntry(Path.GetFileName(file)) { DateTime = DateTime.Now };

        zipStream.PutNextEntry(entry);

        var bufferSize = BufferedSize;
        using (var fs = new BufferedStream(System.IO.File.OpenRead(file), bufferSize))
        {
            int sourceBytes;
            do
            {
                 sourceBytes = fs.Read(buffer, 0, buffer.Length);
                 zipStream.Write(buffer, 0, sourceBytes);
             } while (sourceBytes > 0);
         }
     }

     zipStream.Finish();
     zipStream.Close();
 }

此代码适用于 1 GB 以下的小文件,但当数据达到 7-8 GB 时会引发异常。

4

2 回答 2

5

正如其他人所指出的那样,实际的例外对回答这个问题会有很大帮助。但是,如果您想要一种更简单的方法来创建 zip 文件,我建议您尝试http://dotnetzip.codeplex.com/上提供的 DotNetZip 库。我知道它支持 Zip64(即更大的条目然后 4.2gb 和更多然后 65535 条目),因此它可能能够解决您的问题。然后自己使用文件流和字节数组也更容易使用。

using (ZipFile zip = new ZipFile()) {
    zip.CompressionLevel = CompressionLevel.BestCompression;
    zip.UseZip64WhenSaving = Zip64Option.Always;
    zip.BufferSize = 65536*8; // Set the buffersize to 512k for better efficiency with large files

    foreach (var file in filenames) {
        zip.AddFile(file);
    }
    zip.Save(outpath);
}
于 2012-06-26T13:28:10.263 回答
2

您正在使用 SharpZipLib,对吗?我不确定这是否是一个有效的解决方案,因为我不知道它会引发什么异常,但根据这篇文章这篇文章,它可能是Zip64. 使用与此类似的代码启用它(来自第二个链接的帖子):

UseZip64 = ICSharpCode.SharpZipLib.Zip.UseZip64.Off

或者,根据第一篇文章,在创建存档时指定存档的大小,这应该会自动Zip64解决问题。直接来自第一个链接帖子的示例代码:

using (ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipFilePath)))
{
 //Compression level 0-9 (9 is highest)
 zipStream.SetLevel(GetCompressionLevel());

 //Add an entry to our zip file
 ZipEntry entry = new ZipEntry(Path.GetFileName(sourceFilePath));
 entry.DateTime = DateTime.Now;
 /* 
 * By specifying a size, SharpZipLib will turn on/off UseZip64 based on the file sizes. If Zip64 is ON
 * some legacy zip utilities (ie. Windows XP) who can't read Zip64 will be unable to unpack the archive.
 * If Zip64 is OFF, zip archives will be unable to support files larger than 4GB.
 */
 entry.Size = new FileInfo(sourceFilePath).Length;
 zipStream.PutNextEntry(entry);

 byte[] buffer = new byte[4096];
 int byteCount = 0;

 using (FileStream inputStream = File.OpenRead(sourceFilePath))
 {
     byteCount = inputStream.Read(buffer, 0, buffer.Length);
     while (byteCount > 0)
     {
         zipStream.Write(buffer, 0, byteCount);
         byteCount = inputStream.Read(buffer, 0, buffer.Length);
     }
 }
}
于 2012-06-26T13:08:14.960 回答