简体   繁体   中英

When to close file stream

I reading a file in a zip file using streams like this :

public static Stream ReadFile(Models.Document document, string path, string password, string fileName)
        {
            FileStream fsIn = System.IO.File.OpenRead(Path.Combine(path, $"{document.guid}.crypt"));
            var zipFile = new ZipFile(fsIn)
            {
                //Password = password,
                IsStreamOwner = true
            };



                var zipEntry = zipFile.GetEntry(fileName);
                //zipEntry.AESKeySize = 256;
                Stream zipStream = zipFile.GetInputStream(zipEntry);
                return zipStream;
        }

I'm having trouble closing the filestream fsIn as it is not available when I return from the ReadFile method and if I close it within the method the stream zipStream that I'm returning will be closed. How can I close fsIn but still read the data-stream returned from my method?

You should change your return type to be an object that contains both the parent FileStream and the inner file-stream so that the consumer of your function can close both streams when they need to - alternatively you could subclass Stream with your own type that then assumes ownership of both streams. It's probably simpler to do the former as otherwise you'd have to proxy all Stream methods.

Like so:

sealed class ReadFileResult : IDisposable
    // (use a `sealed` class with a non-virtual Dispose method for simpler compliance with IDisposable)
{
    private readonly FileStream zipFileStream;
    public Stream InnerFileStream { get; }

    internal ReadFileResult( FileStream zipFileStream, Stream innerFileStream )
    {
        this.zipeFileStream = zipFileStream;
        this.InnerFileStream = innerFileStream;
    }

    public void Dispose()
    {
        this.InnerFileStream.Dispose();
        this.zipFileStream.Dispose();
    }
}

public static ReadFileResult ReadFile(Models.Document document, string path, string password, string fileName)
{
    // ...
    return new ReadFileResult( zipFileStream: fsIn, innerFileStream: zipStream );
}

Consumed like so:

void Foo()
{
    using( ReadFileResult rfr = ReadFile( ... ) )
    {
        Stream s = rdr.InnerFileStream;

        // ..
    } 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM