使用zlib / minizip确定压缩块大小

时间:2016-08-06 16:42:14

标签: c++ zip zlib

我正在尝试制作跨平台Appx打包程序(适用于Windows应用商店应用)。格式只是一个带有一些元数据文件的zip。

我需要根据格式的要求制作包含文件哈希的XML文件。问题是每个文件的每个64KB未压缩数据需要一个哈希,还需要compressed size of such 64KB block我该怎么做?

我正在使用Minizip library,如果需要,也可以直接使用zlib

在我看来,我需要避免压缩文件(我想避免)或跳过Minizip的压缩并使用zlib中的原始内容来缩小文件(I&#39 ;我不熟悉zlib的API,知道单独制作每个64KB块是否可行。)

TL; DR:如何判断Zip文件中64KB未压缩数据块的压缩大小?

1 个答案:

答案 0 :(得分:1)

我最终制作了Zip文件"手工制作"并单独压缩块以计算它们的哈希值。

#include <zlib.h>
#define BLOCK_SIZE 65536

z_stream strm;
// Using init2 to avold the zlib header
deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);

int step = 0.

// len is the length of the whole input file
while (len - step > 0) {
    // Get the size of this block (either 64k or the remaining of the file if less)
    long block_size = (len - step) > BLOCK_SIZE ? BLOCK_SIZE : (len - step);

    // strm_in is the input buffer for the compression
    // skipped the buffer allocation for simplicity
    for (int i = 0; i < block_size; i++) {
        strm_in[i] = input_file_buffer[step + i];
    }

    // Calculate the hash (out of the scope for this question)
    // Store in a particular structure for reference later
    BlockData bd;
    bd.hash = make_block_hash(strm_in, block_size);

    // Update the zlib stream info
    // also skipped the out buffer allocation in this sample
    strm.avail_in = block_size;
    strm.avail_out = out_buffer_size;
    strm.next_in = strm_in;
    strm.next_out = strm_out;

    // Save the total bytes for comparison later
    int total_out_before = strm.total_out; 

    // Compress (assume the out buffer size will be always enough)
    deflate(&strm, Z_FULL_FLUSH); // A Full flush here is needed for the APPX format

    // Save the compressed block in the size
    compressed_file->save_buffer(strm_out, strm.total_out - total_out_before);

    // Save the size of the compressed block
    bd.compressed_size = strm.total_out - total_out_before;

    // Store the block data in a list
    blocks_info->push(bd);

    // Move to the next block
    step += block_size;
}

// End the compressed stream
strm.avail_in = 0;
strm.avail_out = out_buffer_size;
strm.next_in = strm_in;
strm.next_out = strm_out;

int total_out_before = strm.total_out;

// Finish the stream
deflate(&strm, Z_FINISH);

// Save the compression tail to the file
compressed_file->save_buffer(strm_out, strm.total_out - total_out_before);

// Clean up
deflateEnd(&strm);

在遇到所有这些问题之后,我找到了一个跨平台open source tool来打包和签署Windows商店应用程序。可能对其他人以及那些认为在Windows之外签名是不可能的人都有帮助。