2011-12-05 56 views
3

特別是我使用Ionic.Zlib.ZlibStreamSystem.Net.Sockets.NetworkStream上執行Zlib壓縮。將兩個單向流組合成雙向流

問題是,ZlibStream是單向流;你可以Read()Write()但不是兩者。您需要兩個獨立的流,一個用於發送,另一個用於接收(一個壓縮和另一個解壓縮)。哪些工作正常,直到您需要將它傳遞給期望單向雙向流(功能均爲Read()Write()功能)的函數爲止。例如,new System.Net.Security.SslStream(Stream base)

我知道我可以編寫一個Stream類,它接受一個寫入流和一個閱讀流,並在覆蓋中調用正確的流。但我希望這已經存在於某個框架中,或者已經有了一個實現。

+1

但是你應該總是壓縮_before_加​​密,不是嗎?這個問題不應該出現。 –

+0

@亨克,那只是一個例子。封裝這個實際流是一個專有的XMPPStream,其中將是一個更有難度的例子。 –

回答

2

我很確定沒有課程會爲你做這個。但是,您需要編寫的包裝類很簡單,不應該花費很長時間。

您可能會繼承,但是如果您分析您的需求和其他可用的流類型,您可能會發現從更具體的類繼承將幫助你。

編輯:由於盧卡斯B的評論。

請注意,流的正常使用流對象要求它們實際上繼承自。否則,您無法將其作爲參數傳遞給期望流的大量函數。

+1

什麼是downvote?如果我錯了一個課程的可用性,爲什麼沒有答案告訴我們它是什麼? –

+1

你將不得不問誰downvoted你。 –

+1

@NickWhaley:我知道。 :)你能告訴我誰downvoted? :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(); 
     } 
    }