2014-09-01 19 views
2

我使用DeflateStream這樣實現的WebSocket壓縮:如何在多個數據塊上使用DeflateStream?

public byte[] Compress(Stream input) 
    { 
     using (var compressStream = new MemoryStream()) 
     using (var compressor = new DeflateStream(compressStream, CompressionMode.Compress)) 
     { 
      input.CopyTo(compressor); 
      compressor.Close(); 

      return compressStream.ToArray(); 
     } 
    } 

這對於第一條消息能正常工作,但我需要保持同樣的壓縮上下文(LZ77滑動窗口),並重新使用它的第二個消息,而不是每次都以新詞典開始。

我目前的解決方法是設置Websockets client_no_context_takeoverserver_no_context_takeover選項,讓對方知道我們不是在循環放氣狀態。

那麼我怎樣才能改變上面的代碼,以便它保留下一次調用deflate'狀態'?

+0

你可以從內存中讀取它在壓縮器中仍然打開的狀態,而不是將其轉換爲數組? – ths 2014-09-03 17:27:25

+0

@speising我這麼認爲。但是壓縮器在調用Close()之前不會刷新任何內存流。 – Muis 2014-09-03 18:01:19

+0

這是一個微型優化,違背了所有向WebSockets添加壓縮的提議。所有不好主意的母親。 – 2014-09-03 21:53:36

回答

-1

實際上,你可以從MemoryStream讀不關閉壓縮機:

input.CopyTo(compressor); 
compressStream.Position = 0; 
var mem2 = new BinaryReader(compressStream); 
mem2.Read(buf, 0, 10000000); 

將產生compressStream的內容。在下一次寫作之前小心地完成定位! (當然,如前所述,你必須保持對象的活性)。

+0

情況並非如此?我試過這個代碼,並且在compressStream中沒有可用的字節,直到壓縮機關閉? – 2015-10-09 00:51:44

0

你的代碼實現了'using',當方法返回時它會處理所有的對象。因此你不能在不同的電話之間保持'狀態'。

嘗試在方法的外部保持對compressorcompressStream的引用。

+0

我知道,但在這種情況下不會有幫助,因爲在讀取結果之前必須調用DeflateStream上的Close(),所以在類級別保留引用似乎毫無意義。 – Muis 2014-09-03 17:15:10

相關問題