2014-06-12 15 views
6

Ben geri kullanıcıya geçirmek istediğiniz bir CryptoStream varsa naif bir yaklaşım olurBir CryptoStream döndürülebilir ve hala her şeyin doğru şekilde elden çıkarılabilir mi?

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 CryptoStream(fsCrypt, transform, CryptoStreamMode.Read); 

    return cs; 
} 

ben CryptoStream atarken FileStreamwill also be disposed yatan biliyoruz. Çalıştığım sorun, rmCrypto ve transform ile ne yapmam? RijndaelManaged ve ICryptoTransform tek kullanımlık sınıflardır, ancak akımın atılması bu iki nesneyi bertaraf etmez.

Bu durumun üstesinden gelmenin doğru yolu nedir?

+1

gibi kullanılmış, 'bunlar yöntemde lokal değişkenler gibi GetDecryptedFileStream'' dan döndükten sonra rmCrypto' ve 'transform' imha edilmelidir. –

+1

@YuvalItzchakov Kapsam dışı bırakılması bertaraf edilmek anlamına gelmez. GC, 'cs' için son başvuruya kadar bu iki nesneyi sonlandırmayacaktır. –

+0

Oh, 'CryptoStream''in bunları bir parametre olarak kabul ettiğini göremedim. –

cevap

5

Akışınızı saran kendi sınıfınızı oluşturmayı düşünürdüm ve bunları elden çıkarmayı yönetebilirsiniz. Bu satırlar boyunca bazı şeyler (üzgünüm - başımın üst kısmındaki dönüşüm nesnesinin türünü bilmiyorum).

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(); 
    } 
} 
+3

Aslında, "Ördekimi sorduktan" sonra soruyu sorduktan sonra ortaya çıkan çözüme çok benzer. CryptoStream' türetebilirsiniz. Bir cevap yazacağım. –

+0

@ScottChamberlain: Lastik ördek kullanmaktan hoşlanıyorum! – Ian

+0

Harika bir çözüm, o şeyleri yayınlamak üzereydi –

5

Ian temel kavram (go upvote him) beni yendi ama bertaraf edilmesi gereken şeyleri sarar türetilmiş bir sınıf yapmak için önemsiz yani CryptoStream kendisi mühürlü değildir.

/// <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(); 
     } 
    } 
} 

senin yönteme göre

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; 
} 
+0

Cevabınızdaki kredi notunu takdir edin :) – Ian

+0

Düşünceleriniz, aslında diğer tüm üyelerin - Uzunluk, ReadByte() vb. - – Ian

+0

base.Dispose() öğesinden sonra transform.Dispose() işleminin gerçekleştirilmesi için daha doğru olun, aksi halde temel sınıfın hala bir referansı olduğu ve kendi imha işlemi sırasında arama yapmayı seçebileceği bir şey attığınızdan emin olun. Algoritma alanınızın ne olduğundan emin değilim (?) ICryptoTransformu oluşturulduğu orijinal nesne buysa, bu, ICryptoTransform oluşturulduğu anda yok edilebilir, böylece daha sonra atılmak üzere bir ref gerekliliğine sahip olmanıza gerek kalmaz. . – redcalx

İlgili konular