在编码流中读写pickle
我们系统中常用的一种文件格式是经过 base64 编码的 pickle 文件。现在,我可以用一些简单的代码将这种简单格式的字符串进行转换,代码如下:
def dumps( objinput ):
"""
Return an encoded cPickle
"""
return cpickle_dumps( objinput ).encode( ENCODING )
def loads( strinput ):
"""
Return an object from an encoded cpickle
"""
return cpickle_loads( strinput.decode( ENCODING ) )
我想实现一个新的功能,叫做“load”,它的工作方式和标准的 pickle load 函数很像,只不过它会从一个数据流中读取足够的字节,然后返回解码后的对象。这里的关键是要读取足够的字节——cPickle.load 函数就是这样做的,它会从数据流中逐个取出字节,直到获取到完整的 pickle 数据。我的新函数需要像这样:
def load( stream_input ):
""""
Return just one object popped from the stream.
If the stream has ended, raise an exception
Do not over-read the stream.
那么,当数据是经过 base64 编码的 pickle 时,我该如何实现呢?这里的难点在于,不太明显是通过包装 cPickle.load 函数还是包装输入流来完成这个任务。另外一个困难是,可能一个字节的 pickle 数据在 base64 编码后会变成多个字节,所以不清楚如何将 stream_input.read(n) 转换成一个可以确保返回 n 字节解码数据的方式,因为输入流是经过 base64 编码的。
1 个回答
1
我觉得你可以通过实现一个类似文件的对象来做到这一点,这样就可以直接传给cPickle.load。
class Base64PickleAdapter:
def __init__(self, base64_input):
...
def read(size=-1):
...
def readline():
... # Can be implemented in terms of read.
cPickle只需要你实现读取和逐行读取这两个功能。你不需要在Base64PickleAdapter.read中返回固定大小的字节。根据read的规定,你可以返回更少的数据,这样可以让实现变得简单一些。