python pickle loadをシーケンス化し、BytesIO(ファイルストリーム、stream)から値を連続的に取得する(getvalue()
3541 ワード
以前のプロジェクトでpickleのシーケンス化とBytesiOのファイルストリームに触れたことがあります.結局今日問題があったファイルpickledumpがBytesIOに入った後、逆に取り出すことができません..長い間調べてみたら、たくさんの資料が紹介されているような気がします..BytesIOがpickleを利用してすべてを読み上げる操作は何編もありません.
役に立つものをいくつか貼ります.
https://stackoverflow.com/questions/30199393/how-can-pickled-byte-data-be-unpickled
https://stackoverflow.com/questions/53485708/how-the-write-read-and-getvalue-methods-of-python-io-bytesio-work
この記事:https://www.twle.cn/t/452
比較的詳細ですが、BytesIOとpickleの組み合わせによる連続読み書きのファイルストリーム操作についてお話ししました.まさに私が必要としています.
私のpickleシーケンス化に対する理解はPythonの任意のオブジェクトを話して、例えばクラス、実力、リスト、辞書などはバイナリに変換して、jsonがとても似ていると感じて、違いは1つのバイナリの1つの文字列ですか?
BytesiOは以前は簡単に見たことがありますが、今日彼の機能を見たのはファイルをメモリに書き込むことですか?ファイルストリームのようです.
これは重要ではありません.キーはpickleとBytesiOを組み合わせた読み書きとファイルポインタの位置です.の
まず重点を置いて、私が解決しなければならない問題です.
開始コードはこのように書いて、a,bを出力することができることを期待して、結果は直接間違いを報告します:EOFError:Ran out of input
理由はio_bufferのポインタの位置は最後で、自然とファイルが読めないので、ポインタの位置を最初にリセットする必要があります.コードをこれに変更すればいいです.
正常出力:a b
または、BytesiOオブジェクトを再生成します.
なお、getvalue、次のコードgetvalue()は、すべての結果abcを取得することが望ましいが、getvalueで得られた結果resをpickle.loads逆シーケンス化後はaしか得られず,resを直接decodeすることで確実にすべてのabcが得られ,長さ33も3文字の長さであることが証明された.
出力結果:
X aq .X bq .X cq . 33 a
pickleを使わなければload書き込み、write書き込みでgetvalueは大丈夫で、すべての結果を得ることができます:abc、高人の指摘を求めます...
出力結果:
3 b'abc'
最後にファイルポインタについてお話しします.主にseekの2つのパラメータです.offset、whence、菜鳥チュートリアルの説明を参照してください. offset--最初のオフセット量、すなわち移動オフセットを表すバイト数 whence:オプションで、デフォルトは0です.offsetパラメータを定義し、どの位置からオフセットを開始するかを示します.0はファイルの先頭から、1は現在位置から、2はファイルの末尾からです.
このコードがない場合:io_buffer.seek(0)、出力結果はabcであるべきであり、ポインタ位置を開始位置にリセットした後、cはaを上書きするので、出力結果:
b'cb'
io_buffer.seek(-1,2)という文2は最後の位置を表し、-1は前に1つの位置を移動することを表すので、bはcによって出力結果を上書きされる:b'ac'
io_buffer.seek(2,2)最後の位置を2つ後ろに移動すると、スペースが2つ増え、結果が出力されます.
b'ab\x00\x00c'
ab c
テストはここまで!
役に立つものをいくつか貼ります.
https://stackoverflow.com/questions/30199393/how-can-pickled-byte-data-be-unpickled
https://stackoverflow.com/questions/53485708/how-the-write-read-and-getvalue-methods-of-python-io-bytesio-work
この記事:https://www.twle.cn/t/452
比較的詳細ですが、BytesIOとpickleの組み合わせによる連続読み書きのファイルストリーム操作についてお話ししました.まさに私が必要としています.
私のpickleシーケンス化に対する理解はPythonの任意のオブジェクトを話して、例えばクラス、実力、リスト、辞書などはバイナリに変換して、jsonがとても似ていると感じて、違いは1つのバイナリの1つの文字列ですか?
BytesiOは以前は簡単に見たことがありますが、今日彼の機能を見たのはファイルをメモリに書き込むことですか?ファイルストリームのようです.
これは重要ではありません.キーはpickleとBytesiOを組み合わせた読み書きとファイルポインタの位置です.の
まず重点を置いて、私が解決しなければならない問題です.
import pickle,io
io_buffer=io.BytesIO()
pickle.dump('a',io_buffer)
pickle.dump('b',io_buffer)
print(pickle.load(io_buffer))
print(pickle.load(io_buffer))
開始コードはこのように書いて、a,bを出力することができることを期待して、結果は直接間違いを報告します:EOFError:Ran out of input
理由はio_bufferのポインタの位置は最後で、自然とファイルが読めないので、ポインタの位置を最初にリセットする必要があります.コードをこれに変更すればいいです.
pickle.dump('a',io_buffer)
pickle.dump('b',io_buffer)
#
io_buffer.seek(0)
print(pickle.load(io_buffer))
print(pickle.load(io_buffer))
正常出力:a b
または、BytesiOオブジェクトを再生成します.
pickle.dump('a',io_buffer)
pickle.dump('b',io_buffer)
# BytesIO
new_io_buffer=io.BytesIO(io_buffer.getvalue())
# io_buffer.seek(0)
print(pickle.load(new_io_buffer))
print(pickle.load(new_io_buffer))
なお、getvalue、次のコードgetvalue()は、すべての結果abcを取得することが望ましいが、getvalueで得られた結果resをpickle.loads逆シーケンス化後はaしか得られず,resを直接decodeすることで確実にすべてのabcが得られ,長さ33も3文字の長さであることが証明された.
pickle.dump('a',io_buffer)
pickle.dump('b',io_buffer)
pickle.dump('c',io_buffer)
res=io_buffer.getvalue()
print(res.decode(errors='ignore'))
print(len(res),pickle.loads(res)
出力結果:
X aq .X bq .X cq . 33 a
pickleを使わなければload書き込み、write書き込みでgetvalueは大丈夫で、すべての結果を得ることができます:abc、高人の指摘を求めます...
io_buffer.write(b'a')
io_buffer.write(b'b')
io_buffer.write(b'c')
res=io_buffer.getvalue()
print(len(res),res)
出力結果:
3 b'abc'
最後にファイルポインタについてお話しします.主にseekの2つのパラメータです.offset、whence、菜鳥チュートリアルの説明を参照してください.
io_buffer.write(b'a')
io_buffer.write(b'b')
io_buffer.seek(0)
io_buffer.write(b'c')
print(io_buffer.getvalue())
このコードがない場合:io_buffer.seek(0)、出力結果はabcであるべきであり、ポインタ位置を開始位置にリセットした後、cはaを上書きするので、出力結果:
b'cb'
io_buffer.write(b'a')
io_buffer.write(b'b')
io_buffer.seek(-1,2)
io_buffer.write(b'c')
# print(io_buffer.read())
print(io_buffer.getvalue())
io_buffer.seek(-1,2)という文2は最後の位置を表し、-1は前に1つの位置を移動することを表すので、bはcによって出力結果を上書きされる:b'ac'
io_buffer.write(b'a')
io_buffer.write(b'b')
io_buffer.seek(2,2)
io_buffer.write(b'c')
# print(io_buffer.read())
#
print(io_buffer.getvalue())
#
print(io_buffer.getvalue().decode())
io_buffer.seek(2,2)最後の位置を2つ後ろに移動すると、スペースが2つ増え、結果が出力されます.
b'ab\x00\x00c'
ab c
テストはここまで!