如何在Python使用ijson解析JSON时获取文件位置?
解决ijson解析大JSON时file.tell()返回文件长度的问题
问题原因
ijson的parse()方法默认会预读取并缓冲文件内容,它会一次性读取大量数据到内存中处理,导致文件对象的指针直接跳到文件末尾,所以调用f.tell()时只会返回文件的总长度,而不是当前解析事件对应的位置。
解决方案
方案1:使用raw_parse跟踪字节块位置
ijson.raw_parse()会返回每个事件对应的原始字节块,我们可以通过累计字节块的长度来跟踪当前解析到的位置。注意要以二进制模式打开文件:
import ijson with open('file', 'rb') as f: current_pos = 0 # raw_parse返回前缀、事件类型、值、对应字节块 for prefix, event, value, bytes_chunk in ijson.raw_parse(f): current_pos += len(bytes_chunk) print(f"当前解析位置(字节偏移): {current_pos}") # 示例:定位特定数据 if prefix == "your_target_key" and event == "string": # 目标数据的起始位置为当前位置减去字节块长度 print(f"找到目标数据,起始位置: {current_pos - len(bytes_chunk)}")
方案2:自定义文件包装器跟踪读取进度
通过包装文件对象,手动记录每次读取的字节数,替代file.tell()的功能:
import ijson class TrackingFile: def __init__(self, file_obj): self.file = file_obj self.current_pos = 0 def read(self, size=-1): data = self.file.read(size) self.current_pos += len(data) return data with open('file', 'r') as f: tracked_file = TrackingFile(f) for prefix, event, value in ijson.parse(tracked_file): print(f"当前已读取字节位置: {tracked_file.current_pos}") # 这里添加匹配特定数据的逻辑
注意事项
因为JSON解析是基于缓冲的,上面两种方法得到的是近似的字节偏移位置,但足够用于在大文件中定位特定数据块的大致位置。
内容的提问来源于stack exchange,提问作者Jenad Morgh
相关产品推荐
相关产品推荐

