2009-05-30 45 views
5

我正在創建一些包括各種文件上傳服務的東西,而且我需要存儲使用zlib的compress()函數壓縮的數據。我通過互聯網發送它已經壓縮,但我需要知道遠程服務器上的未壓縮文件的大小。有沒有什麼辦法可以在不解壓()服務器數據的情況下找到這些信息,只是爲了提高效率?這就是我現在正在做的事情,但如果有一個捷徑,我很樂意接受它。在zlib中獲取未壓縮數據的大小?

順便說一下,它爲什麼叫uncompress?這聽起來對我來說很可怕,我一直認爲它會解壓縮...

+1

我的猜測是爲什麼它被稱爲uncompress是因爲一個名爲pkzip的程序出現在90年代初。有一個叫做pkunzip的類似程序。我認爲「un」卡住了。 http://en.wikipedia.org/wiki/PKZIP – gradbot 2009-05-30 15:05:32

+0

更多關於維基百科的研究表明,這是一場強制更名的官司。 「Katz將他的公用事業名稱改爲PKPAK和PKUNPAK。」後來他們製作了自己的zip版本。 「Katz的朋友Robert Mahoney建議」zip「這個名字(意思是」速度「),他們希望暗示他們的產品比當時的ARC和其他壓縮格式要快。」 因此zip和unzip誕生了。 – gradbot 2009-05-30 15:12:40

+0

啊哈。有趣的:) – AriX 2009-05-31 17:34:26

回答

3

zlib數據格式不具有原始輸入大小的字段,所以我懷疑你將可以在不模擬數據解壓的情況下做到這一點。 gzip format有一個「輸入大小」(ISIZE)字段,可以使用,但可能要避免更改壓縮格式或讓客戶端發送文件大小。

但即使您使用不同的格式,如果您不信任客戶端,您仍然需要運行更昂貴的檢查以確保未壓縮的數據是客戶端所說的大小。在這種情況下,您可以做的是使進程的解壓縮成本更低,確保zlib不會將輸出數據寫入任何地方,因爲您只想知道未壓縮的大小。

4

我對此表示懷疑。我不相信這是基礎zlib庫從內存中提供的東西(雖然它已經使用了7年或8年,但最新的文檔似乎並未指出此功能已被添加)。

一種可能性是轉移另一個包含未壓縮大小的文件(例如,傳輸file.zipfile.zip.size),但似乎充滿危險,特別是如果您的大小錯誤。

另一種替代方法是,如果服務器解壓縮既費時又不必立即完成,可以在優先級較低的後臺任務中完成(如Linux下的nice)。但是,如果尺寸檢查器開始運行(可能會有太多的上傳),則可能存在缺陷。

我傾向於在「爆炸減壓」的角度考慮減壓,而不是個好詞,用:-)

3

如果您使用原始「壓縮」格式上傳,那麼您將不會獲得有關正在上傳的數據大小的信息。 Pax在這方面是正確的。
您可以將它作爲壓縮緩衝區開始處的4字節標題存儲 - 假定文件大小不超過4GB。
一些C代碼作爲一個例子:

uint8_t *compressBuffer = calloc(bufsize + sizeof (uLongf), 0); 
uLongf compressedSize = bufsize; 
*((uLongf *)compressBuffer) = filesize; 
compress(compressBuffer + sizeof (uLongf), &compressedSize, sourceBuffer, bufsize); 

然後發送大小compressedSize +的sizeof(uLongf)的完整compressBuffer。當您收到它在服務器端,您可以使用下面的代碼來取回數據:

// data is in compressBuffer, assume you already know compressed size. 
uLongf originalSize = *((uLongf *)compressBuffer); 
uint8_t *realCompressBuffer = compressBuffer + sizeof (uLongf); 

如果你不信任的客戶端發送正確的尺寸,那麼你將需要進行某種形式的非壓縮數據檢查服務器的大小。使用解壓縮到/ dev/null的建議是合理的。
如果您正在上傳.zip文件,它將包含一個目錄,該目錄會告訴您未壓縮文件的大小。該信息再次構建爲文件格式,但這受到惡意客戶端的限制。