将 Poco Zip 压缩流式传输到 Poco HTTPServerResponse

Stream Poco Zip Compression to Poco HTTPServerResponse

我想直接将目录压缩成 Poco::HTTPServerResponse 流。但是,下载由以下代码生成的 zip 文件会导致存档损坏。我确实知道下面的压缩方法确实适用于本地创建的 zip 文件,因为我已经成功地做了这么多。我错过了什么或者这根本不可能? (Poco v1.6.1)

std::string directory = "/tmp/data";
response.setStatusAndReason(HTTPResponse::HTTPStatus::HTTP_OK);
response.setKeepAlive(true);
response.setContentType("application/zip");
response.set("Content-Disposition","attachment; filename=\"data.zip\"");
Poco::Zip::Compress compress(response.send(),false);
compress.addRecursive(directory,
    Poco::Zip::ZipCommon::CompressionMethod::CM_STORE,
    Poco::Zip::ZipCommon::CompressionLevel::CL_MAXIMUM,
    false, "data");
compress.close();

我成功地使用了相同的技术,只有一点点不同: 压缩方法和压缩级别(CM 和 CL)。

compress.addFile( cacheFile, Poco::DateTime(), currentFile.GetName(), Poco::Zip::ZipCommon::CM_DEFLATE, Poco::Zip::ZipCommon::CL_SUPERFAST );

一个zip文件对应的是DEFLATE算法,所以在解压的时候,你的explorer/archive manager很可能不工作。 要么,要么在 STORE 方法上使用 MAXIMUM 级别是没有意义的(根据定义,STORE 是非压缩的)。

编辑:刚刚试了一下,实际上,这是因为 CM_STORE 内部使用 headers(可能是某种 tar)。将文件添加到 zip 流并关闭它后,Poco 会尝试对 header 进行排序,并将输出流的位置重置为 start 以写入它们。 由于无法在 HTTP 输出流上完成(您的字节已发送!),因此失败。

切换到 CM_DEFLATE 应该可以解决您的问题。