使用Python在10GB级原始数据中查找文本并打印其内存地址
问题分析与解决方案
你的代码目前获取的地址不准确,主要有两个核心问题,同时还有几个细节需要调整,下面一步步给你梳理:
核心错误点
- 块内偏移≠全局文件偏移:你现在打印的
data.index(searchtext)只是当前读取的16MB块内的偏移位置,而不是整个文件的全局偏移地址。你需要累计每次读取的字节数,再加上当前块内的偏移,才能得到正确的文件地址。 - 字符串与二进制数据不匹配:你打开文件用的是
rb(二进制模式),读取的data是二进制字节流,但你用字符串searchtext去匹配,在Python 2里虽然不会报错,但逻辑上应该把搜索文本转换成二进制格式再匹配,避免编码问题。 - 跨块匹配遗漏:如果你的目标字符串刚好横跨两个读取块(比如当前块末尾有一半,下一块开头有另一半),原代码会完全漏掉这个匹配。
修正后的代码
import os filename = "filename.dmp" read_block_size = 2**24 # 16MB 块大小 search_text = "bd:mongo:" # 转换成二进制格式,适配二进制文件读取 search_bytes = search_text.encode('utf-8') # 保存累计读取的总字节数,用于计算全局偏移 total_bytes_read = 0 with open(filename, 'rb') as f: # 为了处理跨块匹配,需要保留上一块的末尾部分(长度为搜索文本长度-1) leftover = b'' while True: data = f.read(read_block_size) if not data: break # 把上一块的末尾和当前块拼接,处理跨块情况 combined_data = leftover + data # 查找所有匹配的位置 start = 0 while True: try: offset_in_combined = combined_data.index(search_bytes, start) # 计算全局偏移:累计读取的字节数 - 上一块保留的长度 + 当前组合数据内的偏移 global_offset = total_bytes_read - len(leftover) + offset_in_combined print(f"Found at global offset: 0x{global_offset:X} (decimal: {global_offset})") # 移动起始位置,查找下一个匹配 start = offset_in_combined + len(search_bytes) except ValueError: break # 保留当前块的最后(len(search_bytes)-1)字节,用于下一块的拼接 leftover = data[-(len(search_bytes)-1):] if len(search_bytes) > 1 else b'' # 更新累计读取的字节数 total_bytes_read += len(data)
关键改进说明
- 全局偏移计算:通过
total_bytes_read累计每次读取的字节数,再结合跨块处理的leftover长度,算出每个匹配的真实文件偏移地址,这个地址就是你需要的“内存地址”(实际是文件中的字节偏移,对应磁盘存储的位置)。 - 二进制匹配:将
search_text编码为二进制search_bytes,和二进制读取的文件数据匹配,避免编码不兼容问题。 - 跨块匹配处理:保留上一块的末尾部分(长度为搜索文本长度减一),和当前块拼接后再查找,确保不会漏掉横跨两个块的目标字符串。
- 多匹配支持:原代码只找第一个匹配,现在改成循环查找当前块内的所有匹配,输出所有对应的偏移地址。
如果你的文件是十六进制格式的(比如你之前定义了he=searchtext.encode('hex')但没用到),那需要把搜索文本转换成十六进制的二进制形式,比如把search_bytes改成bytes.fromhex(search_text.encode('hex')),不过看你的原代码逻辑,应该是直接匹配文本字符串,所以上面的代码应该适用。
内容的提问来源于stack exchange,提问作者samaksh kaushik
相关产品推荐
相关产品推荐

