Node二进制读取转Python时readInt32LE方法适配问题
问题根因
你读不到正确file_size是三个逻辑错误导致的,和语言本身无关:
- 偏移逻辑错误:读完13字节文件名后没有推进读指针,反而又读取13字节数据当size字段,和归档格式完全不匹配
- 读取长度错误:Node端
readInt32LE固定读取4字节长度的小端32位整数,不是13字节 - 解析方式错误:
file_size是二进制整数值,不是文本内容,用latin1解码成字符串必然得到乱码
格式对齐规则
Descent HOG归档的单文件条目结构是固定的,逐字段和Node逻辑对齐即可:
- 前13字节:存储文件名,为C风格字符串,遇到
0x00空字节即结束,文件名格式为名称.3位扩展名 - 紧接4字节:小端序存储的32位有符号整数,值为当前文件的字节长度,对应Node的
readInt32LE - 紧接N字节(N等于上一步读到的文件大小):当前文件的实际二进制内容,读完后指针自动落到下一个条目的起始位置
修正后可运行代码
import struct import os # 二进制模式打开归档文件,不要用文本模式 with open('descent.hog', 'rb') as f: total_size = os.fstat(f.fileno()).st_size offset = 0 while offset < total_size: # 读取13字节文件名 name_raw = f.read(13) offset += 13 # 截断空字节后的无效内容,得到合法文件名 file_name = name_raw.split(b'\x00', 1)[0].decode('latin1') file_type = file_name.split('.')[-1] # 读取4字节转小端32位有符号整数,完全等价于Node的readInt32LE size_raw = f.read(4) offset += 4 file_size = struct.unpack('<i', size_raw)[0] # 读取对应长度的文件内容 content = f.read(file_size) offset += file_size # 打印验证,和Node输出格式一致 print({"file_name": file_name, "type": file_type, "file_size": file_size}) # 需保存提取的文件时取消注释即可 # with open(file_name, 'wb') as out_f: # out_f.write(content)
关键注意点
- Python标准库
struct模块专门处理二进制字节和基础类型的转换:格式符<代表小端序,i代表32位有符号整数,和Node的readInt32LE行为100%一致 - 二进制文件解析全程使用
rb只读二进制模式打开,不要用文本模式读取,避免隐式的编码转换破坏原始字节 - 不要把非文本的二进制字节(比如整数字段、压缩内容、资源数据)强行用文本编码解码,必然出现乱码或逻辑错误
内容的提问来源于stack exchange,提问作者Oli
相关产品推荐
相关产品推荐

