2009-09-11 69 views
2

我正在爲Web內容實施Deflate和GZip壓縮。 .NET Framework DeflateStream的性能非常好(它並不像SharpZipLib那樣好壓縮,但速度更快)。不幸的是,它(和我知道的所有其他庫)錯過了寫入預壓縮數據的函數,如stream.WritePrecompressed(byte [] buffer)。Deflate Compression Stream可以插入預壓縮的數據。 .NET庫存在嗎?

使用此功能可以在流中插入預壓縮塊。這可以減少壓縮此部分的CPU負載並提高Web服務器的總吞吐量。

是否有任何管理庫能夠做到這一點?或者,ComponentAce有沒有比ZLIB.NET好的起點來做到這一點?

+0

你確定它甚至有可能嗎?使用deflate算法進行壓縮會建立基於已經壓縮的數據的內部數據結構,如果向流中注入數據,解壓縮很可能不起作用,除非您還在解壓縮期間去除這些部分。 – 2009-09-11 12:32:04

+0

是的,它應該是可能的,Deflate流被組織在可以重新啓動或更改壓縮的塊中。插入可以開始一個新的塊。如果可能的話,插入的預壓縮塊也可以具有特殊的頭部以適應現有的霍夫曼樹。如果不是,它開始一個新的。 – 2009-09-11 12:58:32

回答

1

另一種方法是清空deflater流(也可能關閉它),以確保所有緩衝壓縮數據都寫入輸出流,然後將預壓縮數據寫入底層輸出流,再次在輸出流的頂部打開deflater流。

0

IIRC#ZipLib允許您設置壓縮級別,您是否嘗試刷新流並將級別降爲0,然後再次提高壓縮級別之前發送已壓縮的數據?

如果您只是考慮性能方面的原因,那麼這可能是一個可接受的解決方案。

+0

這是快速和骯髒的解決方案。實際上,只要您將生成的塊標記爲「不是最後一個」,它就可以與所有庫一起使用。你可以添加一個新的塊。如果插入的塊是5.000字節或更大,則是可以接受的,因爲向後的距離限制爲32.768字節,並且由於速度原因,算法通常僅使用4.096字節。 – 2009-09-17 06:19:34

0

是的,您可以將預壓縮塊插入到zlib流中。從zlib源文件中的zpipe.c示例開始。只有你想要插入預壓縮塊的地方,用Z_FULL_FLUSH替換Z_NO_FLUSH(否則不要使用Z_FULL_FLUSH,因爲壓縮比會受到影響。)

現在壓縮輸出字節對齊,最後一個放氣塊關閉。完全刷新意味着經過預壓縮塊的下一個塊不能包含任何後向引用。

將您的預壓縮塊追加到輸出流(例如memcpy)。將strm.next_out提前到下一個空字節。在離開的地方繼續放氣。

flush = feof(source) ? Z_FINISH : Z_NO_FLUSH; 
ret = deflate(&strm, flush);