Compress large file using SharpZipLib causing Out Of Memory Exception

CathalMF

I have a 453MB XML file which I'm trying to compress to a ZIP using SharpZipLib.

Below is the code I'm using to create the zip, but it's causing an OutOfMemoryException. This code successfully compresses a file of 428MB.

Any idea why the exception is happening, as I can't see why, as my system has plenty of memory available.

public void CompressFiles(List<string> pathnames, string zipPathname)
{
    try
    {
        using (FileStream stream = new FileStream(zipPathname, FileMode.Create, FileAccess.Write, FileShare.None))
        {
            using (ZipOutputStream stream2 = new ZipOutputStream(stream))
            {
                foreach (string str in pathnames)
                {
                    FileStream stream3 = new FileStream(str, FileMode.Open, FileAccess.Read, FileShare.Read);
                    byte[] buffer = new byte[stream3.Length];
                    try
                    {
                        if (stream3.Read(buffer, 0, buffer.Length) != buffer.Length)
                        {
                            throw new Exception(string.Format("Error reading '{0}'.", str));
                        }
                    }
                    finally
                    {
                        stream3.Close();
                    }
                    ZipEntry entry = new ZipEntry(Path.GetFileName(str));
                    stream2.PutNextEntry(entry);
                    stream2.Write(buffer, 0, buffer.Length);
                }
                stream2.Finish();
            }
        }
    }
    catch (Exception)
    {
        File.Delete(zipPathname);
        throw;
    }
}
Daniel A.A. Pelsmaeker

You're trying to create a buffer as big as the file. Instead, make the buffer a fixed size, read some bytes into it, and write the number of read bytes into the zip file.

Here's your code with a buffer of 4096 bytes (and some cleanup):

public static void CompressFiles(List<string> pathnames, string zipPathname)
{
    const int BufferSize = 4096;
    byte[] buffer = new byte[BufferSize];

    try
    {
        using (FileStream stream = new FileStream(zipPathname,
            FileMode.Create, FileAccess.Write, FileShare.None))
        using (ZipOutputStream stream2 = new ZipOutputStream(stream))
        {
            foreach (string str in pathnames)
            {
                using (FileStream stream3 = new FileStream(str,
                    FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    ZipEntry entry = new ZipEntry(Path.GetFileName(str));
                    stream2.PutNextEntry(entry);

                    int read;
                    while ((read = stream3.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        stream2.Write(buffer, 0, read);
                    }
                }
            }
            stream2.Finish();
        }
    }
    catch (Exception)
    {
        File.Delete(zipPathname);
        throw;
    }
}

Especially note this block:

const int BufferSize = 4096;
byte[] buffer = new byte[BufferSize];
// ...
int read;
while ((read = stream3.Read(buffer, 0, buffer.Length)) > 0)
{
    stream2.Write(buffer, 0, read);
}

This reads bytes into buffer. When there are no more bytes, the Read() method returns 0, so that's when we stop. When Read() succeeds, we can be sure there is some data in the buffer but we don't know how many bytes. The whole buffer might be filled, or just a small portion of it. Therefore, we use the number of read bytes read to determine how many bytes to write to the ZipOutputStream.

That block of code, by the way, can be replaced by a simple statement that was added to .Net 4.0, which does exactly the same:

stream3.CopyTo(stream2);

So, your code could become:

public static void CompressFiles(List<string> pathnames, string zipPathname)
{
    try
    {
        using (FileStream stream = new FileStream(zipPathname,
            FileMode.Create, FileAccess.Write, FileShare.None))
        using (ZipOutputStream stream2 = new ZipOutputStream(stream))
        {
            foreach (string str in pathnames)
            {
                using (FileStream stream3 = new FileStream(str,
                    FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    ZipEntry entry = new ZipEntry(Path.GetFileName(str));
                    stream2.PutNextEntry(entry);

                    stream3.CopyTo(stream2);
                }
            }
            stream2.Finish();
        }
    }
    catch (Exception)
    {
        File.Delete(zipPathname);
        throw;
    }
}

And now you know why you got the error, and how to use buffers.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Java

Out of memory exception when decrypt large file using Cipher

From Dev

Writing Large File To Disk Out Of Memory Exception

From Dev

Out of memory exception when using xlsx module with large files

From Dev

Too Many Objects causing out of memory exception

From Dev

Too Many Objects causing out of memory exception

From Dev

ADO Large DataSet throws out of memory exception

From Dev

Perl "out of memory" with large text file

From Dev

Large File - Adding Lines - Out Of Memory

From Dev

Out of memory exception reading and writing text file

From Dev

Uploading file to server throws out of memory exception

From Dev

Hibernate out of memory exception while processing large collection of elements

From Dev

Out of Memory Exception when handling large files in C#

From Dev

C++ allocating large array on heap gives "out of memory exception"

From Dev

C# Large JSON to string causes out of memory exception

From Dev

Entity framework large data set, out of memory exception

From Dev

Hibernate out of memory exception while processing large collection of elements

From Dev

EF - Query Large Data Sets Causes Out Of Memory Exception

From Dev

out of memory when saving a large string data into a text file using open() function

From Dev

Using Picasso library with ImageSwitcher is causing Object out of Memory errors

From Dev

What is causing my Python program to run out of memory using opencv?

From Dev

Download large files using large byte array causes "Out of memory"

From Dev

Out of memory exception while using threads

From Dev

Out Of Memory Exception - Using SqlDataReader and OpenXML

From Dev

Out of memory exception using PdfSharp in a azure webjob

From Dev

compress very large resolution image file using Imagemagick

From Dev

Is it possible to compress a very large file (~30 GB) using gzip?

From Dev

Unable to compress large file with imageminMozjpeg?

From Dev

Exception for no memory while parsing large XML file in SAX parser

From Dev

Read/download large file in PHP without running out of memory

Related Related

  1. 1

    Out of memory exception when decrypt large file using Cipher

  2. 2

    Writing Large File To Disk Out Of Memory Exception

  3. 3

    Out of memory exception when using xlsx module with large files

  4. 4

    Too Many Objects causing out of memory exception

  5. 5

    Too Many Objects causing out of memory exception

  6. 6

    ADO Large DataSet throws out of memory exception

  7. 7

    Perl "out of memory" with large text file

  8. 8

    Large File - Adding Lines - Out Of Memory

  9. 9

    Out of memory exception reading and writing text file

  10. 10

    Uploading file to server throws out of memory exception

  11. 11

    Hibernate out of memory exception while processing large collection of elements

  12. 12

    Out of Memory Exception when handling large files in C#

  13. 13

    C++ allocating large array on heap gives "out of memory exception"

  14. 14

    C# Large JSON to string causes out of memory exception

  15. 15

    Entity framework large data set, out of memory exception

  16. 16

    Hibernate out of memory exception while processing large collection of elements

  17. 17

    EF - Query Large Data Sets Causes Out Of Memory Exception

  18. 18

    out of memory when saving a large string data into a text file using open() function

  19. 19

    Using Picasso library with ImageSwitcher is causing Object out of Memory errors

  20. 20

    What is causing my Python program to run out of memory using opencv?

  21. 21

    Download large files using large byte array causes "Out of memory"

  22. 22

    Out of memory exception while using threads

  23. 23

    Out Of Memory Exception - Using SqlDataReader and OpenXML

  24. 24

    Out of memory exception using PdfSharp in a azure webjob

  25. 25

    compress very large resolution image file using Imagemagick

  26. 26

    Is it possible to compress a very large file (~30 GB) using gzip?

  27. 27

    Unable to compress large file with imageminMozjpeg?

  28. 28

    Exception for no memory while parsing large XML file in SAX parser

  29. 29

    Read/download large file in PHP without running out of memory

HotTag

Archive