2009-05-30 10 views
5

ファイルアップロードサービスのソートを含むものを作成しています.zlibのcompress()関数で圧縮したデータを格納する必要があります。既に圧縮されたインターネットを介して送信しますが、リモートサーバー上の圧縮されていないファイルサイズを知る必要があります。効率性のために、サーバー上のデータを最初に解凍することなくこの情報を把握する方法はありますか?それが今私がやっている方法ですが、もしショートカットがあればそれを取るのが大好きです。zlibの圧縮されていないデータのサイズを取得しますか?

ところで、なぜそれを圧縮解除といいますか?それは私にはかなり恐ろしいと思う、私はいつも解凍すると思った...

+1

私は90年代初めに登場したpkzipというプログラムのために、なぜそれがuncompressと呼ばれるのかと思います。 pkunzipと呼ばれるプログラムがありました。私は "un"の周りにこだわったと思う。 http://en.wikipedia.org/wiki/PKZIP – gradbot

+0

ウィキペディアに関するさらなる研究は、それが名前の変更を余儀なくされた訴訟であったことを示唆している。 "Katzは彼のユーティリティの名前をPKPAKとPKUNPAKに変更しました。"その後、彼らはzipという独自のバージョンを作った。 Katzの友人であるRobert Mahoneyは、「Zip」という名前(スピードを意味する)を提案していました。彼らは、ARCや他の圧縮フォーマットよりも速いということを暗示したかったのです。 したがって、zipとunzipが生まれました。 – gradbot

+0

ああ〜面白い:) – AriX

答えて

3

:-)使用することをお用語、「爆発解凍」の観点で解凍を考えていない傾向がありますデータの圧縮解除をシミュレートすることなく、これを実行できます。 gzip formatには「入力サイズ」フィールド(ISIZE)がありますが、圧縮フォーマットを変更したり、クライアントがファイルサイズを送信したりすることは避けてください。

しかし、異なるフォーマットを使用する場合でも、クライアントを信頼しない場合は、さらに高価なチェックを実行して、非圧縮データがクライアントのサイズであることを確認する必要があります。この場合、をuncompress-to-/ dev/nullのプロセスを安価にし、zlibが非圧縮のサイズを知りたいので、出力データをどこにでも書き込まないようにします。

+0

ありがとうございます。私は/ dev/nullへの解凍を考えていませんでした:) – AriX

4

私はそれを疑う。これは基本的なzlibライブラリがメモリから提供するものとは信じられません(私が使ってから7〜8年経ちましたが、最新のドキュメントはこの機能が追加されたとは思われません)。

圧縮されていないサイズ(たとえば、file.zipfile.zip.sizeの両方を含む)を含む別のファイルを転送する可能性がありますが、特にサイズが間違っている場合は危険です。

もう1つの選択肢は、サーバーの圧縮解除に時間がかかるが、すぐに実行する必要がない場合は、優先度の低いバックグラウンドタスク(Linuxではniceなど)で行うことです。しかし、サイズチェッカーが遅れて実行されると(アップロードが多すぎる)、欠点もあります。

そして私はzlibのフォーマットは、元の入力サイズのフィールドを持っていないので、私は疑う

+0

ええ、私はいつもサーバーにサイズを教えてもらえますが、ユーザーは簡単にこれを悪用することができ、何か複雑なハッシュチェックや何かをしたくないのです。 – AriX

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へのuncompressの使用の提案は合理的なものです。
.zipファイルをアップロードする場合は、圧縮されていないファイルのサイズを示すディレクトリが含まれています。この情報はファイル形式に組み込まれていますが、これは悪質なクライアントの影響を受けます。

関連する問題