6

ある種のファイルアップロードサービスを含むものを作成しています。zlibのcompress()関数で圧縮されたデータを保存する必要があります。すでに圧縮されているインターネット経由で送信しますが、リモートサーバー上の非圧縮ファイルサイズを知る必要があります。効率のために、最初にサーバー上のデータをuncompress()せずにこの情報を把握する方法はありますか?それが今のやり方ですが、近道があればやってみたいです。

ちなみに、なぜそれは解凍と呼ばれるのですか?それは私にはかなりひどいように聞こえます、私はいつもそれが解凍されるだろうと思っていました...

4

3 に答える 3

4

疑わしい。これは、基盤となるzlibライブラリがメモリから提供するものではないと思います(使用してから7〜8年が経過しましたが、最新のドキュメントには、この機能が追加されたことが示されていません)。

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

もう1つの方法は、サーバーの解凍に時間がかかるが、すぐに実行する必要がない場合は、優先度の低いバックグラウンドタスク(niceLinuxの場合など)で実行することです。ただし、サイズチェッカーが遅れて実行され始めると(アップロードが多すぎる)、欠点が生じる可能性があります。

そして、私は「爆発的減圧」の観点から減圧を考える傾向がありますが、使用するのに適した用語ではありません:-)

于 2009-05-30T13:54:32.003 に答える
4

生の「圧縮」形式を使用してアップロードしている場合、アップロードされているデータのサイズに関する情報はありません。Paxはこの点で正しいです。
ファイルサイズが4GBを超えないと仮定すると、圧縮バッファーの先頭に4バイトのヘッダーとして保存できます。
例としていくつかの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ファイルをアップロードする場合は、圧縮されていないときのファイルのサイズを示すディレクトリが含まれています。この情報はファイル形式に組み込まれていますが、これも悪意のあるクライアントの影響を受けます。

于 2009-05-30T15:30:49.937 に答える
3

zlib 形式には元の入力サイズのフィールドがないため、データの解凍をシミュレートせずにそれを行うことができるとは思えません。gzip 形式には「入力サイズ」( ) フィールドがあり、これISIZEを使用できますが、圧縮形式を変更したり、クライアントにファイル サイズを送信させたりしたくない場合があります。

ただし、別の形式を使用したとしても、クライアントを信頼していない場合は、圧縮されていないデータがクライアントが言うサイズであることを確認するために、よりコストのかかるチェックを実行する必要があります。この場合、/dev/null へのuncompress-to-to-/dev/nullプロセスのコストを下げて、圧縮されていないサイズを知りたいだけなので、zlib が出力データをどこにも書き込まないようにすることができます。

于 2009-05-30T15:19:17.963 に答える