【问题标题】:Python - Reading a UTF-8 encoded string byte-by-bytePython - 逐字节读取 UTF-8 编码的字符串
【发布时间】:2017-02-04 07:10:16
【问题描述】:

我有一个返回 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?

【问题讨论】:

    标签: python python-2.7 unicode encoding utf-8


    【解决方案1】:

    正确的解决方案是读取直到你到达终止字节,然后转换为 UTF-8(这样你就有了所有字符):

    mybytes = bytearray()
    while True:
        x = read_next_byte()
        if x == 0:
            break
        mybytes.append(x)
    my_string = mybytes.decode('utf-8')
    

    以上是您原始代码的最直接翻译。有趣的是,这是 two arg 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:是的。在 Py3 中,执行 my_string.encode('utf-8') 会更直观一些(得到 bytes,其行为类似于 Py3 中的不可变 bytearrays);不过,在 Py2 中,encode 为您提供 str,它通过 len 1 str 的字符进行迭代,而不是通过 ints 从 0-255 进行迭代。无论哪种方式,您都可以迭代结果并调用写入函数:for b in bytearray(my_string, 'utf-8'): write_one_byte(b)
    猜你喜欢
    • 1970-01-01
    • 2011-08-16
    • 2013-05-11
    • 1970-01-01
    • 2013-01-31
    • 2014-06-09
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多