2

Python オブジェクトは、文字列と数値のネストされたリストです。

ファイルは書き込み用に 'w' ('wb' ではありません) として開かれましたが、cPickle は protocol=1 (つまりバイナリ) を使用するように指示されました。

シリアライゼーションとデシリアライゼーションのコードは、Linux で正常に機能しました。Windows マシン (Python 2.6) に保存されたオブジェクトを復元できません。

行末のため、Windowsでファイルを明示的に「wb」として開く必要があることを(今では)理解しています。つまり、書き込まれたオブジェクトはネストされたリストであり、 \n が含まれていないため、それが問題になるかどうかはわかりません。

私の質問は、データを回復するために何ができるでしょうか?

の結果は次のprint repr(open(fqfn, 'rb').read(15))とおりです。

 ']q\x01(]q\x02]q\x03(U\x0fst'

どんなアイデアでも大歓迎です。


mhawke の提案に従ってl = cPickle.load(open(fqfn, 'r'))試しましたが、Windows から EOF エラーが返されます。

ファイルを 16 進エディタで直接開いた場合、 のインスタンスを単純に置き換えてから'\r\n'、バイナリ モードを使用1013て復元できますか?

シリアル化への入力は次のようなものでした。

[['start', 3454654], [1234567645, -1 , 99], [1234567900, 1 , 56], ...]

入力の順序、各リストの長さ、およびいくつかの値 (たとえば、先頭の文字列といくつかの数字) を知っています。

したがって、私の質問は、バイナリ エンコーディングを処理するスクリプトを作成して逆シリアル化できるかどうかだと思います。Python オブジェクトに入れる必要はありません。ascii で十分です。

4

1 に答える 1

0

Windows マシン上でファイルをテキスト モード'r'(つまり ではないモード)で開いて、ファイルを unpickle しようとしたことがあると思います。'rb'運が良ければ、次のように動作するはずです。

import cPickle
l = cPickle.load(open(fqfn, 'r'))

データに新しい行が含まれていない可能性がありますが、10 や 13 などの値が含まれている可能性があります。次の点を考慮してください。

>>> cPickle.dumps(10, protocol=1)
'K\n.'
>>> cPickle.dumps(256, protocol=1)
'M\x00\x01.'
>>> cPickle.dumps(266, protocol=1)
'M\n\x01.'

ascii 10 は改行文字であり、バイナリ ピクル モードではそのように格納されるため、最初の '\n' が存在します。同様に、266 (256+10) をピクルすると、出力に '\n' も表示されます。

Windows では、「テキスト」モードで開かれたファイルに書き込むときに、Python は自動的に '\n' を '\r\n' に変換します。また、テキスト モードで読み取るときに、'\r\n' を '\n' に変換します。そのため、Windows マシンで「テキスト」モードでファイルを開くと、問題が解決するはずです。

于 2012-08-15T02:42:21.480 に答える