如何在Python中读取包含二进制数据的sys.stdin(忽略错误)?

4

如何读取 sys.stdin,但忽略解码错误? 我知道存在 sys.stdin.buffer ,我可以读取二进制数据,然后使用 .decode('utf8', errors='ignore') 进行解码,但我想逐行读取 sys.stdin 。 也许我可以以 errors='ignore' 选项重新打开 sys.stdin 文件?


1
把解码放在try块中,将解码错误作为异常处理怎么样? - user2261062
@SembeiNorimaki,它怎么能帮助?我需要执行sys.stdin.read(),或者更具体地说,是for line in sys.stdin,但它会抛出UnicodeDecodeError。如果我捕获了它,我该如何读取这一行呢?我只需要忽略它无法读取的符号。这一行大多数情况下包含ASCII字符,但也可能包含ASCII之外的字符,所以我需要忽略它们或用“?”替换。 - g00dds
@SembeiNorimaki,数据不重要,我希望能够预期任何数据,包括纯二进制数据(即使通常是文本)。我不想能够解码所有数据,我希望能够使用bytes.decode函数忽略我无法解码的数据。如果我像open(filename,'r',errors ='ignore')一样读取实际文件,我可以做到这一点,但我想读取sys.stdin,但它已经是一个打开的文件描述符,所以我不知道如何设置errors ='ignore'选项。 - g00dds
请看这里... https://dev59.com/WKvka4cB1Zd3GeqPvZbU - Mark Setchell
дҪ иҝҳеҸҜд»ҘйҖҗиЎҢиҜ»еҸ–sys.stdin.bufferгҖӮ - Keith
显示剩余2条评论
2个回答

1

如Mark Setchell所提到的,从这里找到了三种解决方案。

import sys
import io

def first():
    with open(sys.stdin.fileno(), 'r', errors='ignore') as f:
        return f.read()

def second():
    sys.stdin = io.TextIOWrapper(sys.stdin.buffer, errors='ignore')
    return sys.stdin.read()

def third():
    sys.stdin.reconfigure(errors='ignore')
    return sys.stdin.read()


print(first())
#print(second())
#print(third())

使用方法:

$ echo 'a\x80b' | python solution.py
ab

0

您可以在PYTHONIOENCODING环境变量上设置错误处理程序选项:这将影响sys.stdinsys.stdoutsys.stderr始终使用“backslashreplace”)。PYTHONIOENCODING接受可选的编码名称和可选的错误处理程序名称,前面加上冒号,因此“UTF8”,“UTF8:ignore”和“:ignore”都是有效值。

$  cat so73335410.py
import sys

if __name__ == '__main__':
    data = sys.stdin.read()
    print(data)
$
$  echo hello | python so73335410.py
hello

$  echo hello hello hello hello | zip > hello.zip
  adding: - (deflated 54%)
$
$  cat hello.zip | PYTHONIOENCODING=UTF8:ignore python so73335410.py
UYv>
  -▒
UY  HW@'PKv>

  ▒-PK,-/>PKmPK/>
$ 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接