3

I want to create a zip file in C# that will include almost 8 GB of data. I am using the following code:

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();
 }

This code works for small files under 1 GB, but it throws an exception when the data reaches 7-8 GB.

Ricardo Altamirano
  • 14,650
  • 21
  • 72
  • 105
Gaurav Gupta
  • 157
  • 4
  • 13

2 Answers2

5

As others have pointed out, the actual exception would have helped a lot in answering this. However, if you want an easier way to create zip-files I would suggest you try the DotNetZip-library available at http://dotnetzip.codeplex.com/. I know it has support for Zip64 (ie larger entries then 4.2gb and more then 65535 entries) so it might be able to solve your problem. It is also a lot easer to use then working with filestreams and bytearrays yourself.

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);
}
Karl-Johan Sjögren
  • 16,544
  • 7
  • 59
  • 68
  • Can u tell me one thing,sir....if i'm using your code..for handle the large File(4 gb)...it doesn't reduce the size of file(i.e. created zip file) ...it will shows 4gb as rar file.. – THE LIFE-TIME LEARNER Dec 17 '19 at 10:16
  • Yes this doesn't affect the size of the output, it just allows the size to be larger than ~4.2gb. If you want to make even smaller files you should look into some other compression (though this will probably also be a lot slower to compress). – Karl-Johan Sjögren Dec 17 '19 at 14:36
2

You're using SharpZipLib, correct? I'm not sure if this is a valid solution because I don't know what exception it throws, but based on this post and this post, it may be a problem with Zip64. Either enable it using code similar to this (from the second linked post):

UseZip64 = ICSharpCode.SharpZipLib.Zip.UseZip64.Off

or, based on the first post, specify the size of the archive when you create it, which should automatically take care of the Zip64 problem. Sample code directly from the first linked post:

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);
     }
 }
}
Community
  • 1
  • 1
Ricardo Altamirano
  • 14,650
  • 21
  • 72
  • 105