2017-05-02 24 views
0

我试图通过行改为子行:从TextIOWrapper读引起的UnicodeDecodeError

proc = subprocess.Popen(self.monitor_logcat_cmd, shell=True, stdout=subprocess.PIPE, 
         bufsize=1, universal_newlines=True) 

while proc.poll() is None: 
    line = proc.stdout.readline() 
    print("Process line: " + str(line)) 

它的工作原理,但在某些时候,我得到错误:

Exception in thread Thread-14: 
Traceback (most recent call last): 
    File "/Users/F1sherKK/anaconda3/lib/python3.6/threading.py", line 916, in _bootstrap_inner 
    self.run() 
    File "/Users/F1sherKK/Dev/Python/AutomationTestSupervisor/session/SessionThreads.py", line 46, in run 
    line = proc.stdout.readline() 
    File "/Users/F1sherKK/anaconda3/lib/python3.6/codecs.py", line 321, in decode 
    (result, consumed) = self._buffer_decode(data, self.errors, final) 
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc0 in position 89: invalid start byte 

有什么办法来添加/指定编码子进程的标准输出?我想补充错误“忽略”。

有没有其他方法可以解决这个问题?

+0

那么过程产生什么字节,关掉'universal_newlines'?你知道过程产生什么编码吗? –

+0

'monitor_logcat_cmd'包含什么?什么命令在shell中运行?你是否设置了“LANG”或“LC_CTYPE”环境变量? –

+0

monitor_logcat_cmd是'adb -s 5554 logcat'它实时从Android设备读取日志。它可以包含我猜测的各种编码。例如,日志中可以有表情符号。我没有设置任何env变量。 – F1sher

回答

0

可能刚刚设置的errors关键字参数Popen()'ignore'。从documentation

If encoding or errors are specified, or universal_newlines is true, the file objects stdin, stdout and stderr will be opened in text mode using the encoding and errors specified in the call or the defaults for io.TextIOWrapper .

但是,很显然你的过程中不使用UTF-8的编码输出。您可能想要弄清楚a)它可以配置为产生不同的编码,或者b)使用什么编码并将其配置(使用关键字参数为Popen())。

+0

谢谢。我用'errors =“ignore”'得到了临时解决方案。我之前没有尝试过,因为PyCharm在尝试使用它时发生了“意外的争论”错误。但它有效。我认为可能很难为此日志设置单一编码。我认为它应该是UTF-8,但有时单个元素不是UTF-8。我不是编码专家,但这就是我对此的理解。在我的情况下,我需要从设备上保存20k行日志,所以如果他们中很少有人会“忽略错误”,我不认为这会对我造成任何问题。尽管我用各种编码来填充实验。谢谢。 – F1sher