【发布时间】:2018-10-27 20:44:28
【问题描述】:
我正在将一些主要的十六进制输入读入 Python3 脚本。然而,系统
设置为使用 UTF-8 并且当从 Bash shell 管道到脚本时,我保留
得到以下UnicodeDecodeErrorerror:
UnicodeDecodeError: ('utf-8' codec can't decode byte 0xed in position 0: invalid continuation byte)
根据其他 SO 答案,我在 Python3 中使用sys.stdin.read() 读取管道输入,如下所示:
import sys
...
isPipe = 0
if not sys.stdin.isatty() :
isPipe = 1
try:
inpipe = sys.stdin.read().strip()
except UnicodeDecodeError as e:
err_unicode(e)
...
使用这种方式配管时有效:
# echo "\xed\xff\xff\x0b\x04\x00\xa0\xe1" | some.py
<output all ok!>
但是,使用原始格式不会:
# echo -en "\xed\xff\xff\x0b\x04\x00\xa0\xe1"
▒▒▒
▒▒
# echo -en "\xed\xff\xff\x0b\x04\x00\xa0\xe1" | some.py
UnicodeDecodeError: ('utf-8' codec can't decode byte 0xed in position 0: invalid continuation byte)
还尝试了其他有希望的 SO 答案:
# echo -en "\xed\xff\xff\x0b\x04\x00\xa0\xe1" | python3 -c "open(1,'w').write(open(0).read())"
# echo -en "\xed\xff\xff\x0b\x04\x00\xa0\xe1" | python3 -c "from io import open; open(1,'w').write(open(0).read())"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/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 0xed in position 0: invalid continuation byte
从我目前了解到的情况来看,当您的终端遇到UTF-8 序列时,它是expecting 它后面跟着1-3 个其他字节,如下所示:
UTF-8 是一种可变宽度字符编码,能够使用 一到四个 8 位字节 对 Unicode 中的所有有效代码点进行编码。 因此,在 前导字节(
0xC2 - 0xF4范围内的第一个 UTF-8 字符)之后的任何内容都将跟随 1-3 连续字节,在里面 范围0x80 - 0xBF。
但是,我不能总是确定我的输入流来自哪里,它很可能是原始数据,而不是上面的 ASCII HEX 版本。所以我需要以某种方式处理这个原始输入。
我查看了一些替代方案,例如:
将
open("myfile.jpg", "rb", buffering=0)与raw i/o 一起使用使用来自bytes的
bytes.decode(encoding="utf-8", errors="ignore")或者只使用open(...)
但我不知道他们是否或如何像我想要的那样读取管道输入流。
如何让我的脚本也处理原始字节流?
PS。是的,我已经阅读了大量类似的 SO 问题,但没有一个能够充分处理这个 UTF-8 输入错误。最好的是this one。
这不是重复的。
【问题讨论】:
-
您的输入是否(某些)恰好是十六进制数字并不重要。但是“原始”是指任意 二进制 输入,对吧?
-
@DavisHerring 是的,二进制。但是,我不同意我的问题是重复的,只是因为其中可能有一个与我的远程相关的嵌入式答案。这个问题(你链接的)与我的完全不同,当遇到我的问题或错误时,任何人都不太可能搜索这些词。
-
它几乎没有“远程相关”:这个问题涉及读取和写入二进制数据,但是一个答案的前三句话完全回答了这个问题。我通过搜索与这个问题相关的术语找到了它,尽管我同意它的标题有点缺乏“规范的
buffer问题”。
标签: python python-3.x character-encoding pipe stdin