【问题标题】:Reading from TextIOWrapper causes UnicodeDecodeError从 TextIOWrapper 读取会导致 UnicodeDecodeError
【发布时间】:2017-05-02 21:24:07
【问题描述】:

我尝试逐行读取子进程:

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

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

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

【问题讨论】:

  • 那么进程会产生什么字节,关闭universal_newlines?你知道这个过程会产生什么编码吗?
  • monitor_logcat_cmd 究竟包含什么?在 shell 中运行什么命令?你是在设置LANG 还是LC_CTYPE 环境变量?
  • monitor_logcat_cmd 是adb -s 5554 logcat 它正在从Android设备实时读取日志。我猜它可以由各种编码组成。例如,日志中可以有表情符号。我没有设置任何环境变量。

标签: python encoding subprocess stdout popen


【解决方案1】:

可以只需将errors 关键字参数设置为Popen()'ignore'。来自documentation

如果指定了 encodingerrors,或者 universal_newlines 为 true,则文件对象 stdinstdoutstderr 将使用调用中指定的 encodingerrors 或 @987654325 的默认值以文本模式打开@。

但是,很明显您的进程不使用 UTF-8 对其输出进行编码。您可能想弄清楚 a) 是否可以将其配置为生成不同的编码,或者 b) 使用什么编码并进行配置(使用 Popen()encoding 关键字参数)。

【讨论】:

  • 谢谢。我得到了errors="ignore" 的临时解决方案。我之前没有尝试过这个,因为当我尝试使用 PyCharm 时出现“意外参数”错误。然而它确实有效。我认为可能很难为此日志设置单一编码。我认为它应该是 UTF-8,但有时有单个元素不是 UTF-8。我不是编码专家,但这就是我的理解。就我而言,我需要从我的设备中保存大约 20k 行日志,所以如果其中很少有“忽略的错误”,我认为这不会给我带来任何问题。不过,我用各种编码填充实验。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-22
  • 2020-10-07
  • 2018-07-05
  • 1970-01-01
相关资源
最近更新 更多