adamhathcock / sharpcompress

SharpCompress is a fully managed C# library to deal with many compression types and formats.
MIT License
2.25k stars 479 forks source link

Wrapped Streams are always disposed - 0.21 #382

Open t246246 opened 6 years ago

t246246 commented 6 years ago

This program

using SharpCompress.Compressors.BZip2;
using System;
using System.IO;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var inFile = new FileStream("../../Program.cs", FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                using (var memoryStream = new MemoryStream())
                {
                    using (var bzipStream = new BZip2Stream(memoryStream, SharpCompress.Compressors.CompressionMode.Compress, true))
                    {
                        inFile.CopyTo(bzipStream);
                        bzipStream.Close();
                    }                    
                    var length = memoryStream.Length;
                    Console.Out.WriteLine(length);
                }
            }
        }
    }
}

worked in version 0.20.0 (as long as the 3rd argument of BZip2Stream is true.) It was the only way I managed to find getting bzip'ed bytes in memory.

It no longer works current 0.21.1 --- memoryStream is closed when trying to get Length. So how to get bzip'ed imege to memory stream (without using temporary file?)

adamhathcock commented 6 years ago

Don't allow the stream to be disposed. Use NonDisposingStream like:

        [Fact]
        public void TestBZip2InMemory()
        {
            using (var inFile = new FileStream("../../../ADCTest.cs", FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                using (var memoryStream = new MemoryStream())
                {
                    using (var bzipStream = new BZip2Stream(new NonDisposingStream(memoryStream), SharpCompress.Compressors.CompressionMode.Compress, true))
                    {
                        inFile.CopyTo(bzipStream);
                        bzipStream.Close();
                    }                    
                    var length = memoryStream.Length;
                    Console.Out.WriteLine(length);
                }
            }
        }
adamhathcock commented 6 years ago

FYI, there was a breaking change in behavior in regards to how stream disposal is handled. I used to fight the good fight and try to make it so that Streams wouldn't dispose/close wrapped Streams they didn't own. However, this is rarely the case for many reasons. Now, you should assume disposing a Stream/Reader will also dispose the wrapped Stream.

adamhathcock commented 6 years ago

Also updated USAGE: https://github.com/adamhathcock/sharpcompress/blob/master/USAGE.md