2016-09-26 75 views
4

我有一个设备返回一个UTF-8编码的字符串。我只能逐字节地读取数据,而读取则由一个值为0x00的字节结束。Python - 读取一个字节的UTF-8编码字符串

我正在为其他人访问我的设备和返回字符串做一个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?

回答

3

正确的解决办法是阅读,直到你遇到终止字节,然后转换为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') 
+0

神奇。这似乎很好。所以要做相反的事情,并编码一个字节阵列,我可以使用这个权利? 'my_bytes = bytearray(my_string,'utf-8')' 并且只是遍历my_bytes来发送单个字节。 – Will

+0

@ will:是的。在Py3中,执行'my_string.encode('utf-8')'(它可以让你获得'bytes',它的行为就像Py3中的不变的'bytearray')。在Py2中,'encode'会得到'str',它由字符'len' 1'str'迭代,而不是从0-255的int。无论哪种方式,您都可以迭代结果并调用write函数:'for bytearray(my_string,'utf-8')中的b:write_one_byte(b)' – ShadowRanger