如何使用zlib压缩和解压UTF-8数据的正确方法是什么?

7

我有一个非常长的JSON消息,其中包含超出ASCII表的字符。 我将其转换为字符串,如下所示:

messStr = json.dumps(message,encoding='utf-8', ensure_ascii=False, sort_keys=True)

我需要使用一个限制大小为X字节的服务来存储这个字符串。我想把JSON字符串分成长度为X的片段并单独存储它们。在此过程中,我遇到了一些问题(描述在这里),所以我想压缩字符串切片以解决这些问题。我尝试过以下方法:

ss = mStr[start:fin]    # get piece of length X
ssc = zlib.compress(ss) # compress it

当我这样做时,zlib.compress 返回以下错误:
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf1' in position 225: ordinal not in range(128)

如何正确压缩UTF-8字符串,以及正确的解压缩方法是什么?

2个回答

14

对Martijn的回答进行一点补充。 我在Enthought博客上读到了一个很棒的一行语句,可以让您无需在自己的代码中导入zlib。

安全地压缩字符串(包括您的json转储)看起来像这样:

ssc = ss.encode('utf-8').encode('zlib_codec')

解压回 utf-8 的方法如下:

ss = ssc.decode('zlib_codec').decode('utf-8')

希望这有所帮助。

这是对我有用的,而不是其他答案。感谢史诗般的解决方案!+1 - Anshu Dwibhashi
@nurettin,这段代码在提问时是在Python2上运行的。从您的错误信息来看,似乎您正在使用Python3。 - Lynx-Lab
我喜欢这个答案,因为它避免了单独导入“zlib”。但我怀疑这会惩罚代码的可读性,因为直接使用“zlib”模块是最重要的,而上面的“zlib_codec”只是其中的一部分。感谢您提供的好答案! - Jason R Stevens CFA

7
您的JSON数据没有采用UTF-8编码。在json.dumps()函数中,encoding参数指示其如何解释Python字节字符串中的message(例如输入),而不是如何对输出进行编码。因为您使用了ensure_ascii=False,所以它根本没有编码输出。
在压缩之前对数据进行编码:
ssc = zlib.compress(ss.encode('utf8'))

再次解压缩时,无需从UTF-8解码;如果输入是字节串,则json.loads()函数默认为UTF-8编码。


1
以上代码仅适用于Python 3.x,因为zlib包(终于)将byte-array作为输入而非字符串。在Python 2.7中,这不起作用,因为zlib.compress采用字符串并使用ascii编解码器将输入转换为byte-array,因此出现了OP的错误消息。 - Slawomir
@Debriter 是的,问题在这个问题中是Python 2所特有的。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接