Python - 逐字节读取UTF-8编码的字符串

5
我有一个设备,返回一串UTF-8编码的字符。我只能逐字节读取,并且读取以值为0x00的字节终止。
我正在编写Python 2.7函数,供他人访问我的设备并返回字符串。
在之前的设计中,当设备仅返回ASCII时,我在循环中使用了以下代码:
x = read_next_byte()
if x == 0:
    break
my_string += chr(x)

其中 x 是从设备读取的最新字节值。

现在设备可以返回一个 UTF-8 编码的字符串,但我不确定如何将返回的字节转换为 UTF-8 编码的字符串/Unicode。

chr(x) 当 x>127 时会导致错误,因此我认为使用 unichr(x) 可能会起作用,但这假定传递的值是完整的 Unicode 字符值,而我只有 0-255 的一部分。

那么我该如何将从设备获取的字节转换为可用于 Python 的字符串并仍然处理完整的 UTF-8 字符串呢?

同样地,如果我在 Python 中获得了一个 UTF-8 字符串,我该如何将其拆分成单个字节以发送到我的设备并仍然保持 UTF-8 呢?

1个回答

4
正确的解决方案是读取直到遇到终止字节,然后在那个时候转换为UTF-8(这样你就拥有了所有字符):
mybytes = bytearray()
while True:
    x = read_next_byte()
    if x == 0:
        break
    mybytes.append(x)
my_string = mybytes.decode('utf-8')

上面是你原始代码的最直接翻译。有趣的是,这是其中一种情况,可以使用两个参数 iter来大大简化代码,将你的C风格有状态字节读取函数转换为Python迭代器,让你可以一行完成工作。
# If this were Python 3 code, you'd use the bytes constructor instead of bytearray
my_string = bytearray(iter(read_next_byte, 0)).decode('utf-8')

太棒了。看起来运行得很好。那么要做相反的操作,将一个字节数组编码,我可以使用这个对吗?my_bytes = bytearray(my_string, 'utf-8') 然后只需循环遍历 my_bytes 来发送单个字节。 - Will
@Will:是的,在Py3中,使用my_string.encode('utf-8')更加直观(这会得到bytes,在Py3中表现得像不可变的bytearray);但在Py2中,encode会得到str,它按其字符的长度1迭代str,而不是从0-255迭代int。无论哪种方式,您都可以迭代结果并调用写入函数:for b in bytearray(my_string, 'utf-8'): write_one_byte(b) - ShadowRanger

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