web-dev-qa-db-ja.com

エラー「_pickle.UnpicklingError:invalid load key、 ''。」の原因は何ですか?

配列に5000個のデータ要素を保存しようとしています。この5000個の要素は、既存のファイル上のストレージです(したがって、空ではありません)。

しかし、エラーが発生しており、何が原因なのかわかりません。

に:

def array():

    name = 'puntos.df4'

    m = open(name, 'rb')
    v = []*5000

    m.seek(-5000, io.SEEK_END)
    fp = m.tell()
    sz = os.path.getsize(name)

    while fp < sz:
        pt = pickle.load(m)
        v.append(pt)

    m.close()
    return v

でる:

line 23, in array
pt = pickle.load(m)
_pickle.UnpicklingError: invalid load key, ''.
11
Xcecution

酸洗は逐次的ではなく、再帰的です。したがって、リストをピクルするために、pickleは含まれるリストのピクルを開始し、最初の要素をピクルします。最初の要素に飛び込み、最初の要素がシリアル化されるまで依存関係とサブ要素をピクルします。その後、リストの次の要素に移動し、リストを最終的に終了し、囲んでいるリストのシリアル化を完了するまで、というように続きます。要するに、いくつかの特別な場合を除いて、再帰的なpickleを順次として扱うことは困難です。 dumpを特別な方法で使用する場合は、loadでよりスマートなパターンを使用することをお勧めします。

最も一般的なピクルは、単一のdumpですべてをファイルにピクルすることです。しかし、その後は、単一のloadで一度にloadする必要があります。ただし、ファイルハンドルを開いて複数のdump呼び出し(たとえば、リストの各要素、または選択した要素のタプル)を実行すると、loadはそれをミラーリングします...ファイルを開きますすべてのリスト要素を取得してリストを再構築できるまで、複数のload呼び出しを処理および実行します。ただし、特定のリスト要素のみを選択的にloadすることは依然として容易ではありません。そのためには、dictなどのパッケージを使用して、リスト要素をklepto(要素またはチャンクのインデックスをキーとして)として保存する必要があります。 dictをいくつかのファイルに透過的に挿入し、特定の要素を簡単にロードできるようにします。

ピクルファイルに複数のオブジェクトを保存およびロードしますか?

11
Mike McKerns

これはあなたの特定の問題とは関係ないかもしれませんが、gzipを使用してpickleアーカイブが作成されたときに同様の問題がありました。

たとえば、圧縮ピクルアーカイブがこのように作成された場合、

import gzip, pickle
with gzip.open('test.pklz', 'wb') as ofp:
    pickle.dump([1,2,3], ofp)

開こうとするとエラーがスローされます

 with open('test.pklz', 'rb') as ifp:
     print(pickle.load(ifp))
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
_pickle.UnpicklingError: invalid load key, ''.

ただし、gzipを使用してpickleファイルを開くと、すべてが調和します

with gzip.open('test.pklz', 'rb') as ifp:
    print(pickle.load(ifp))

[1, 2, 3]
5
mishaF

pickleモジュールの一般的な使用法は、特定のオフセットを探して個々の値を手動でロードしようとして何を達成しようとしているのか完全にはわかりません。

# save data to a file
with open('myfile.pickle','wb') as fout:
    pickle.dump([1,2,3],fout)

# read data from a file
with open('myfile.pickle') as fin:
    print pickle.load(fin)

# output
>> [1, 2, 3]

リストをダンプした場合、リストをロードします。各アイテムを個別にロードする必要はありません。

-5000オフセットをシークする前にエラーが発生したと言っているので、読み込もうとしているファイルが破損している可能性があります。

元のデータにアクセスできる場合は、新しいファイルに保存して、例のように読み取ってみることをお勧めします。

3
yurib

これらのファイルをディスクまたは他の手段で転送した場合、適切に保存されていない可能性があります。

0
foladev