2016-09-26 78 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