我希望使用 zlib
压缩字符串并将其作为字符串附加到文本消息中。我有几个问题:
a.将“二进制”字符串与普通字符串组合有问题吗?例如,通过套接字发送如下所示的字符串是否存在问题:
MSG 10=12 20=x\x9c+(\xc0\x00\x00S3\x08Q 33=hansz
我问这个问题是因为打开文件时通常会声明他是否打算以二进制模式读取,但我从未完全理解这一点。
b.我可以确定某些字符不会出现在压缩字符串中吗?例如,如果压缩字符串将包含一些字符序列,例如 x\x9c 33=eve
,我将无法正确解析消息。如果我知道空格永远不会出现在 zlib
压缩字符串中,我可以进行一些字符串分割;如果我知道引号和撇号不会出现,我可能会使用 shlex
split。
c.我的意图是使用 zlib.compress(str(obj))
或 zlib.compress(pickle.dumps(obj))
作为 pickle ,并使用 eval(zlib.decompress(s))
或 pickle.loads(zlib.decompress(s))
用于解封。你觉得有道理吗?第一个想法不太安全(因为 eval
从来都不是那么安全),但它是一个内部系统,所以我同意它,另一方面,压缩在大多数情况下都较短案例,并且同样快。您认为这是一个好的做法吗?
d.我希望这些消息简短的原因是我希望稍后通过套接字发送它们。我不熟悉套接字,但是,我知道它们往往会读取小(4k?)缓冲区,因此我尝试使我的消息不比这长得多。
最佳答案
a.组合字节和 unicode 字符串的问题如下:字母数量超过 255 个。因此,历史上,创建了数百种编码将不同的字母放入一个字节中。
>>> print b'\xE4'.decode('cp1251') # russian d
д
>>> print b'\xE4'.decode('cp1252') # german ae
ä
字母有不同的含义。为了不丢失这些字母的含义,您可以使用 unicode。
>>> print u'\u00e4\u0434'
äд
但是,当您看到字节时,您可能不知道编码。所以你不能立即将 unicode 和 bytes 结合起来,因为一个字节可能是不同的字母。
使用'UTF-8'
作为 future 几年的编码。如果需要,它会使用多个字节并存储所有字母。
b. zlib 获取字节并输出字节。它可以包含任何字节。
c. zlib.compress(pickle.dumps(obj))
和 pickle.loads(zlib.decompress(s))
完全没问题。 Pickle 获取对象并返回字节。与 zlib.compress(repr(obj))
和 eval(zlib.decompress(s))
相比,您可以保存和存储更多对象。 pickle
与 eval
一样安全。如果您需要保存评估,请查看 import ast
ast.literal_eval
或使用 json
而不是 pickle
。
d.确保知道一条消息何时结束以及另一条消息何时开始。我认为你可以使用 zlib.decompressobj 来实现这一点。否则 zib 可能会感到困惑。套接字可以发送远多于 4k 字节的数据。缓冲区意味着套接字最多可保存 4k 字节,并且在从缓冲区中取出字节之前不想接收更多字节。如果您使用 TCP,您可以发送无尽的字节流,并且不会丢失任何内容。
关于python - 通过 pickle/eval 和 zlib 进行序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21750567/