Can a CryptoStream be returned and still have everything dispose correctly?

我与影子孤独终老i 提交于 2019-12-01 04:01:40

I'd consider creating your own class that wraps the stream and then you can manage the disposal of these. Somethings along these lines (sorry - don't know the type of the transform object off top of my head).

public CryptoStreamWrapper : Stream, IDisposable
{
    public CryptoStreamWrapper(CryptoStream stream, RijndaelManaged rmCrypto, IDisposable transform)
    {
        this.transform = transform;
        this.rmCrypto = rmCrypto;
        this.stream = stream;
    }

    public void Dispose()
    {
        this.transform.Dispose();
        this.rmCrypto.Dispose();
        this.stream.Dispose();
    }
}
Scott Chamberlain

Ian beat me to the basic concept (go upvote him), but CryptoStream itself is not sealed so it is trivial to make a derived class that wraps the things that need to be disposed.

/// <summary>
/// Creates a class that creates a <see cref="CryptoStream"/> and wraps the disposing action of all the associated objects 
/// </summary>
class ReturnableCryptoStream : CryptoStream
{
    private readonly ICryptoTransform _transform;
    private readonly IDisposable _algorithm;

    public ReturnableCryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode) 
        : this(stream, transform, mode, null)
    {
    }

    public ReturnableCryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode, IDisposable algorithm) 
        : base(stream, transform, mode)
    {
        _transform = transform;
        _algorithm = algorithm;
    }

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
        if (disposing)
        {
            if (_transform != null)
                _transform.Dispose();

            if (_algorithm != null)
                _algorithm.Dispose();
        }
    }
}

Used like

public Stream GetDecryptedFileStream(string inputFile, byte[] key, byte[] iv)
{
    var fsCrypt = new FileStream(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read);
    var rmCrypto = new RijndaelManaged();
    var transform = rmCrypto.CreateDecryptor(key, iv);
    var cs = new ReturnableCryptoStream(fsCrypt, transform, CryptoStreamMode.Read, rmCrypto);

    return cs;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!