簡體   English   中英

我如何使用散列和泡菜來保存/加載對象

[英]How do I use hashing and pickle to save/load objects

所以我正在遵循一本關於使用隨機文件的書中的指南,並使用以下代碼來保存一些對象

import pickle
from carRec import carRec

cars = [carRec(1, "Ford", "Escort"), carRec(2, "Ford", "Focus"), carRec(3, "Ford", "Mustang")]

#output to carsFile
carFile = open("carsRand.dat", "wb")

for i in range(0,3):
   address = hash(cars[i].vehicleID)
   carFile.seek(address)
   pickle.dump(cars[i], carFile)

carFile.close()

然后用於加載數據

import pickle
from carRec import carRec

carFile = open("cars.dat", "rb")
cars = []
counter = 1

try:
    while True:
        location = hash(counter)
        carFile.seek(location)
        cars.append(pickle.load(carFile))
        counter += 1
except EOFError:
    print("done")

carFile.close()  

問題是,當我嘗試重新加載數據時,出現以下錯誤

_pickle.UnpicklingError: invalid load key, ''.

快速查看 dat 文件使我認為數據的寫入工作不正常。 我相信,當使用散列和查找函數來確定寫入/讀取的位置時,您需要考慮記錄的大小(以字節為單位)。 如果是這種情況,我如何 a) 確保所有記錄的大小相同,以及 b) 找出單個記錄的大小?

此代碼的問題在於汽車對象在寫入時會覆蓋先前寫入的汽車對象。 這可以通過直接酸洗列表來解決:

import pickle
with open("cars.dat", "wb") as f:
    pickle.dump(cars, f)

然后可以加載:

with open("cars.dat", "rb") as f:
    cars = pickle.load(f) 

如果您絕對必須單獨腌制對象,則可以使用len(pickle.dumps(obj, -1))確定對象的腌制大小

此外,您是否考慮過使用shelve模塊? 這是將簡單的 Python 對象持久化到文件的最簡單方法。

編輯:確保記錄大小相同的最簡單方法是不使用泡菜。 但是,您可以在記錄旁邊存儲記錄的大小:

import pickle
import struct

with open("cars.dat", "wb") as f:
    for car in cars:
        size = len(pickle.dumps(car, -1))
        f.write(struct.pack("<I", size))
        pickle.dump(car, f)

此代碼在每條記錄之前存儲 4 個字節的長度信息。 然后可以使用struct.unpack("<I", f.read(4))[0]加載此長度數據

然后,您還可以將每個(長度、數據)對的偏移量存儲在文件的開頭,以允許讀取第 n 條記錄而無需遍歷所有先前的記錄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM