4

他のサーバーからいくつかのファイルをダウンロードし、圧縮せずにzipアーカイブとして返すWebサーバーの機能を作成しています。

ダウンロードしたすべてのファイルのサイズがわかっている場合、ZIPアーカイブの最終的なサイズを確認するにはどうすればよいですか?

これは私が今取り組んでいるコードです。コメントされた行により、ZIPアーカイブが破損しました。

public void Download()
{
    var urls = Request.Headers["URLS"].Split(';');
    Task<WebResponse>[] responseTasks = urls
        .Select(it =>
        {
            var request = WebRequest.Create(it);
            return Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse(null, null), request.EndGetResponse);
        })
        .ToArray();

    Task.WaitAll(responseTasks);

    var webResponses = responseTasks.Where(it => it.Exception == null).Select(it => it.Result);

    var totalSize = webResponses.Sum(it => it.ContentLength + 32);

    Response.ContentType = "application/zip";
    Response.CacheControl = "Private";
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    // Response.AddHeader("Content-Length", totalSize.ToString(CultureInfo.InvariantCulture));

    var sortedResponses = webResponses.OrderBy(it => it.ContentLength);

    var buffer = new byte[32 * 1024];

    using (var zipOutput = new ZipOutputStream(Response.OutputStream))
    {
        zipOutput.SetLevel(0);

        foreach (var response in sortedResponses)
        {
            var dataStream = response.GetResponseStream();

            var ze = new ZipEntry(Guid.NewGuid().ToString() + ".jpg");
            zipOutput.PutNextEntry(ze);

            int read;
            while ((read = dataStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                zipOutput.Write(buffer, 0, read);
                Response.Flush();
            }

            if (!Response.IsClientConnected)
            {
                break;
            }
        }

        zipOutput.Finish();
    }

    Response.Flush();
    Response.End();
}
4

3 に答える 3

8

私は同じ問題を抱えていて、ZIP-specを読んで次の解決策を思いつきました:

zip_size = num_of_files * (30 + 16 + 46) + 2 * total_length_of_filenames + total_size_of_files + 22

と:

  • 30: 固定部分Local file header
  • 16: オプション: のサイズData descriptor
  • 46: 固定部分Central directory file header
  • 22: 固定部分End of central directory record (EOCD)

ただし、これはファイルのコメントと zip の合計を考慮していません。圧縮はストア (レベル 0) です。

これは、私が書いたZIP実装で機能します。nicolay-olshevsky が指摘したように、他のコンプレッサーの動作mightは少し異なります。

于 2013-10-15T11:55:53.573 に答える
2

ZIP ファイルは、いくつかのファイルごとのレコードといくつかのアーカイブごとのレコードで構成されています。それらは複雑な構造をしており、使用するアーカイバによってサイズが異なる場合があります。ただし、同じ圧縮オプションで同じ実装を使用する場合、アーカイブのサイズは、入力のサイズと入力ファイル名のサイズのみに依存します。

したがって、1 つまたは 2 つのファイルでアーカイブを作成し、それらのサイズ、入力ファイルのサイズ、およびファイル名のサイズがわかれば、アーカイブごとのペイロード サイズ、ファイルごとのペイロード サイズ、およびファイル名からのアーカイブ サイズの依存関係を計算できます (ファイル名は 2 つの場所で使用されます)。

于 2012-12-10T14:34:33.483 に答える