2011-12-05 12 views
3

特に、System.Net.Sockets.NetworkStreamでZlib圧縮を行うにはIonic.Zlib.ZlibStreamを使用しています。2つの一方向ストリームを双方向ストリームに結合する

問題は、ZlibStreamは一方向ストリームです。 Read()またはWrite()とすることができますが、両方を行うことはできません。送信用と受信用の2つの別々のストリームが必要です(1つは圧縮、もう1つは復元)。単一の双方向ストリーム(両方ともRead()Write()の機能)を期待している関数に渡す必要があるまで、うまく動作します。たとえば、new System.Net.Security.SslStream(Stream base)となります。

書き込みストリームと読み取りストリームを受け取り、オーバーライドで正しいストリームを呼び出すStreamクラスを書くことができます。しかし、私はこれがフレームワークのどこかに既に存在しているか、すでに利用可能な実装が存在することを望んでいました。

+1

ただし、必ず_before_暗号化を圧縮する必要がありますか?問題は起こらないはずです。 –

+0

@Henk、これは単なる例です。このストリームをカプセル化する実際のストリームは独自のXMPPSストリームであり、その意味のある例を与えるのがさらに難しくなります。 –

答えて

2

私はあなたにこれを行うクラスはないと確信しています。しかし、あなたが書く必要があるラッパークラスはシンプルで、とても長い時間を費やすべきではありません。

おそらくストリームから継承しますが、あなたはあなたのニーズや他の利用可能なストリームの種類を分析する場合、あなたはより具体的なクラスから継承することはあなたを助けることがあります。

:Lucas Bさんのコメントが原因です。

ストリームオブジェクトの通常の用途は、彼らが実際にストリームから継承している必要がありますのでご注意ください。それ以外の場合は、ストリームを必要とする多数の関数にパラメータとして渡すことはできません。

+1

ダウンボートは何でしたか?私がクラスを利用できるかどうかについて間違っている場合、それが何であるかを示す答えがないのはなぜですか? –

+1

あなたは誰でもあなたを落胆させて尋ねなければなりません。 –

+1

@NickWhaley:私はそれを知っています。あなたは誰に落札したのか教えていただけますか? :P –

2

フレームワークにまだ存在しない場合は十分に簡単です。

public class StreamRWJoin : Stream { 
     public Stream WriteStream { get; set; } 
     public Stream ReadStream { get; set; } 
     private bool leaveOpen; 

     public StreamRWJoin(Stream readfrom, Stream writeto, bool leaveOpen = false) { 
      WriteStream = writeto; ReadStream = readfrom; 
      this.leaveOpen = leaveOpen; 
     } 

     public override bool CanRead { 
      get { return ReadStream.CanRead; } 
     } 

     public override bool CanSeek { 
      get { return false; } 
     } 

     public override bool CanWrite { 
      get { return WriteStream.CanWrite; } 
     } 

     public override void Flush() { 
      WriteStream.Flush(); 
     } 

     public override long Length { 
      get { throw new NotImplementedException(); } 
     } 

     public override long Position { 
      get { 
       throw new NotImplementedException(); 
      } 
      set { 
       throw new NotImplementedException(); 
      } 
     } 

     public override int Read(byte[] buffer, int offset, int count) { 
      return ReadStream.Read(buffer, offset, count); 
     } 

     public override long Seek(long offset, SeekOrigin origin) { 
      throw new NotImplementedException(); 
     } 

     public override void SetLength(long value) { 
      throw new NotImplementedException(); 
     } 

     public override void Write(byte[] buffer, int offset, int count) { 
      WriteStream.Write(buffer, offset, count); 
     } 

     public override void Close() { 
      if (!leaveOpen) 
       try { 
        WriteStream.Close(); 
       } finally { 
        ReadStream.Close(); 
       } 
     } 

     public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { 
      return ReadStream.BeginRead(buffer, offset, count, callback, state); 
     } 
     public override int EndRead(IAsyncResult asyncResult) { 
      return ReadStream.EndRead(asyncResult); 
     } 

     public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { 
      return WriteStream.BeginWrite(buffer, offset, count, callback, state); 
     } 
     public override void EndWrite(IAsyncResult asyncResult) { 
      WriteStream.EndWrite(asyncResult); 
     } 

     public override int ReadByte() { 
      return ReadStream.ReadByte(); 
     } 
     public override void WriteByte(byte value) { 
      ReadStream.WriteByte(value); 
     } 

     public override int ReadTimeout { 
      get { 
       return ReadStream.ReadTimeout; 
      } 
      set { 
       ReadStream.ReadTimeout = value; 
      } 
     } 

     public override int WriteTimeout { 
      get { 
       return WriteStream.WriteTimeout; 
      } 
      set { 
       WriteStream.WriteTimeout = value; 
      } 
     } 

     public override bool CanTimeout { 
      get { 
       return ReadStream.CanTimeout || WriteStream.CanTimeout; 
      } 
     } 

     public override int GetHashCode() { 
      return ReadStream.GetHashCode()^WriteStream.GetHashCode(); 
     } 

     protected override void Dispose(bool disposing) { 
      if (disposing && !leaveOpen) { 
       try { 
        ReadStream.Dispose(); 
       } finally { 
        WriteStream.Dispose(); 
       } 
      } 
     } 

     public override string ToString() { 
      return "Read: " + ReadStream.ToString() + ", Write: " + WriteStream.ToString(); 
     } 
    }