指点成金-最美分享吧

登录

如何获取 LZMA2 文件 (.xz / liblzma) 的未压缩大小

佚名 举报

技术标签:

【中文标题】如何获取 LZMA2 文件 (.xz / liblzma) 的未压缩大小【英文标题】:How to get the uncompressed size of an LZMA2 file (.xz / liblzma) 【发布时间】:2010-01-31 13:14:54 【问题描述】:

我正在寻找一种方法来获取使用 xz 实用程序压缩的 LZMA2 / .xz 文件的未压缩流大小。

我正在使用 Windows/Linux 中的 liblzma 来完成这项任务,所以我想我正在 liblzma 中寻找一些可以解决问题的 C/C++ API。

【问题讨论】:

【参考方案1】:

我想我找到了解决办法。

这是一个非常粗略的代码示例,但似乎可以正常工作。

我假设我有一个 do_mmap() 函数,它将整个文件作为只读映射到内存中,并返回映射的总大小。这自然可以适应使用 read/fread/ReadFile 或任何其他 File API。

extern size_t get_uncompressed_size(const char *filename)   lzma_stream_flags stream_flags;   int file_size;   const uint8_t *data = (uint8_t *) do_mmap(filename, &file_size);   // 12 is the size of the footer per the file-spec...   const uint8_t *footer_ptr = data + file_size - 12;   // Something is terribly wrong   if (footer_ptr < data)      do_unmap((void *)data, file_size);     return -1;      // Decode the footer, so we have the backward_size pointing to the index   lzma_stream_footer_decode(&stream_flags, (const uint8_t *)footer_ptr);   // This is the index pointer, where the size is ultimately stored...   const uint8_t *index_ptr = footer_ptr - stream_flags.backward_size;   // Allocate an index   lzma_index *index = lzma_index_init(NULL);   uint64_t memlimit;   size_t in_pos = 0;   // decode the index we calculated   lzma_index_buffer_decode(&index, &memlimit, NULL, index_ptr, &in_pos, footer_ptr - index_ptr);   // Just make sure the whole index was decoded, otherwise, we might be   // dealing with something utterly corrupt   if (in_pos != stream_flags.backward_size)      do_unmap((void *)data, file_size);     lzma_index_end(index, NULL);     return -1;      // Finally get the size   lzma_vli uSize = lzma_index_uncompressed_size(index);   lzma_index_end(index, NULL);   return (size_t) uSize;

【讨论】:

我想用lzma2原生库来写hadoop压缩编解码器。如果你有任何API文档或者你对压缩/解压缩相关的理解会很有帮助。 两个问题。 (1) 在调用lzma_index_buffer_decode之前需要初始化memlimit,或者在某些情况下会返回LZMA_MEMLIMIT_ERROR。 (2) 你不应该打电话给lzma_index_initindex 的初始值被lzma_index_buffer_decode 忽略。 是的 Patrick 并将 12 替换为 LZMA_STREAM_HEADER_SIZE “流标头和流尾标大小相同”参见 lzma/stream_flags.h。【参考方案2】:

从sourceforge 下载了源代码并查看了这里,我从主头文件 LzmaLib.h

中引用了这个/*Lzma解压缩--------------在: dest - 输出数据 destLen - 输出数据大小 src - 输入数据 srcLen - 输入数据大小出去: destLen - 处理后的输出大小 srcLen - 处理后的输入大小回报: SZ_OK - 好的 SZ_ERROR_DATA - 数据错误 SZ_ERROR_MEM - 内存分配错误 SZ_ERROR_UNSUPPORTED - 不支持的属性 SZ_ERROR_INPUT_EOF - 它需要输入缓冲区(src)中的更多字节*/MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, const unsigned char *props, size_t propsSize);

看起来destLen是未压缩数据的大小。

希望这会有所帮助,最好的祝福,汤姆。

【讨论】:

我认为 XZ 文件格式不是直接的 LZMA,而是各种压缩算法的封装

以上是关于如何获取 LZMA2 文件 (.xz / liblzma) 的未压缩大小的主要内容,如果未能解决你的问题,请参考以下文章