Search code examples
c#memorystreamgzipstream

C# Cannot access a closed stream while copying GZipStream to MemoryStream


I've been trying to convert a GZipStream into a MemoryStream and then convert it to a byte array without having to write any files to the hard drive. I've been trying to copy it to a MemoryStream but I've been getting this error: Unhandled Exception: System.ObjectDisposedException: Cannot access a closed Stream.

I've looked at some of the other solutions, but I haven't been able to successfully implement them into what I'm trying to accomplish.

GZipStream decompressedStream = Decompress(new FileInfo(args[0]));
        using (var finalStream = new MemoryStream())
        {
            decompressedStream.CopyTo(finalStream);
            byte[] decompressedBytes = new byte[finalStream.Length];
        }

EDIT: Somebody wanted me to add the code for Decompress() so here it is

public static GZipStream Decompress(FileInfo fileToDecompress)
    {
        using (FileStream originalFileStream = fileToDecompress.OpenRead())
        {
            string currentFileName = fileToDecompress.FullName;
            string newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length) + " (decompressed)";
            using (FileStream decompressedFileStream = File.Create(newFileName))
            {
                using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
                {
                    return decompressionStream;
                }
            }
        }
    }

Solution

  • The issue is here:

    using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
    {
         return decompressionStream;
    }
    

    using statement (see this article) disposes the stream and you can't use it outside of the block. Move your MemoryStream handling inside this block and return byte[] from the method.

    Something like this should work:

    public static byte[] Decompress(FileInfo fileToDecompress)
    {
        using (FileStream originalFileStream = fileToDecompress.OpenRead())
        {
            string currentFileName = fileToDecompress.FullName;
            string newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length) + " (decompressed)";
            using (FileStream decompressedFileStream = File.Create(newFileName))
            {
                using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
                using (var finalStream = new MemoryStream())
                {
                    decompressionStream.CopyTo(finalStream);
                    return finalStream.ToArray();
                }
            }
        }
    }