You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python生成LZMA文件未压缩大小字段全0xFF与lzma.exe输出不一致问题

问题原因

你遇到的头字段Uncompressed Size全为0xFF的问题,核心是两个使用错误:

  1. 你只调用了LZMACompressor.compress()方法写入了部分压缩数据,没有调用flush()方法获取压缩结束后的剩余数据、结束标记,也没有完成完整的文件头补全逻辑。
  2. Python lzma库的FORMAT_ALONE(即LZMA单独文件格式)的流式压缩模式默认假设输入是未知长度的流,所以会把头中的未压缩大小字段填为全0xFF,这个取值在LZMA规范里代表「未压缩大小未知」,解压时读到流结束即可。而7z官方的lzma.exe压缩时默认会计算输入文件的总大小,写入头字段。

修正代码

你可以直接用更简单的lzma.compress便捷接口,自动处理压缩全流程,输出和lzma.exe逻辑对齐的文件:

import lzma

input_path = "file_split0_test.bin"
output_path = "file_split0_test.lzma"

with open(input_path, "rb") as f_in:
    raw_data = f_in.read()
# 指定和lzma.exe -d23匹配的字典大小2^23=8MB
compressed_data = lzma.compress(raw_data, format=lzma.FORMAT_ALONE, dict_size=1 << 23)

with open(output_path, "wb") as f_out:
    f_out.write(compressed_data)

也可以用lzma.open的上下文管理器简化写入逻辑:

import lzma

input_path = "file_split0_test.bin"
output_path = "file_split0_test.lzma"

with open(input_path, "rb") as f_in, \
     lzma.open(output_path, "wb", format=lzma.FORMAT_ALONE, dict_size=1 << 23) as f_out:
    f_out.write(f_in.read())

补充说明

如果你坚持用LZMACompressor手动处理流,必须在写完所有输入数据后调用flush(),把剩余的压缩数据和结束标记写入文件:

lzma_machine = lzma.LZMACompressor(format=lzma.FORMAT_ALONE, dict_size=1 << 23)
with open(input_path, "rb") as f_in, open(output_path, "wb") as f_out:
    f_out.write(lzma_machine.compress(f_in.read()))
    # 必须调用flush补全数据
    f_out.write(lzma_machine.flush())

这种模式下未压缩大小字段还是会保留0xFF,但文件本身可以正常解压,不会影响使用。如果需要和lzma.exe的头字段完全一致,优先使用前两种便捷接口即可。

内容的提问来源于stack exchange,提问作者Justin Yau Wei Shun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 03:42:04