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

Python使用Pickle更新二进制文件异常:仅处理第二条记录

问题:Pickle更新二进制文件时仅处理前两条记录,第三条未被处理

原代码片段

import pickle

up={}
f=False
f1=open("BINARY3.dat","rb+")
f1.seek(0)
try:
    while True:
        pos=f1.tell()
        up=pickle.load(f1)                
        if up['Year']<2005:
            up['Status']='Disposed'                   
            f1.seek(pos)
            pickle.dump(up,f1)
            f=True

except EOFError:
    if f==False:
        print('no record found')
    else:
        print("record")
    f1.close()

问题现象

执行代码后,仅前两条FIR记录被修改,第三条记录未被处理也未输出。

预期输出

Enter option: 1-Make/Add Records, 2-Check status of fir, 3-update data, 4-leave: 3
{'Court_est': 'highcourt', 'Police_Station': 'kolkata', 'FIR': 1, 'Year': 2000, 'Status': 'Disposed'}
{'Court_est': 'specialcourt', 'Police_Station': 'pune', 'FIR': 2, 'Year': 2002, 'Status': 'Disposed'}
{'Court_est': 'supremecourt', 'Police_Station': 'delhi', 'FIR': 3, 'Year': 2004, 'Status': 'Disposed'}

问题原因

原代码用rb+模式直接在文件内修改记录,pickle.dump()写入的修改后数据字节长度大概率和原记录不一致,会覆盖后续记录的部分数据,导致第三条记录的Pickle结构被破坏,后续pickle.load()提前触发EOFError,无法读取和处理第三条记录。

解决方案(基于Pickle模块)

采用「全量读取-内存修改-覆盖写入」的方式,避免直接修改文件时的覆盖问题,同时匹配预期的选项输入逻辑:

import pickle

# 处理选项输入
option = input("Enter option: 1-Make/Add Records, 2-Check status of fir, 3-update data, 4-leave: ")
if option == '3':
    records = []
    # 1. 读取所有记录到内存
    try:
        with open("BINARY3.dat", "rb") as f:
            while True:
                try:
                    records.append(pickle.load(f))
                except EOFError:
                    break
    except FileNotFoundError:
        print("No records found")
        exit()
    
    # 2. 修改符合条件的记录
    updated = False
    for rec in records:
        if rec['Year'] < 2005:
            rec['Status'] = 'Disposed'
            updated = True
    
    # 3. 重新写入所有记录并输出结果
    if updated:
        with open("BINARY3.dat", "wb") as f:
            for rec in records:
                pickle.dump(rec, f)
        # 打印修改后的所有记录
        for rec in records:
            print(rec)
    else:
        print('no record found')
else:
    # 其他选项逻辑可自行补充
    print("Invalid option or other functionality not implemented")

关键说明

  • 用with语句自动管理文件生命周期,无需手动调用close()
  • 全量读取记录到列表,修改后用wb模式覆盖写入,确保所有记录的Pickle结构完整
  • 加入了选项输入逻辑,匹配预期输出的开头提示
  • 处理了文件不存在的异常情况,增强代码健壮性

内容的提问来源于stack exchange,提问作者Siddharth N

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:30:22