【问题标题】:read files with different encoding format using sys.stdin in python3在 python3 中使用 sys.stdin 读取具有不同编码格式的文件
【发布时间】:2018-06-23 18:52:12
【问题描述】:

我有许多使用 UTF-8 或 GBK 编码的文件。我的系统编码是 UTF-8 (LANG=zh_CN.UTF-8),所以我可以轻松读取 UTF-8 编码的文件。但我也必须使用 GBK 读取文件编码。我在这里关注Python 3: How to specify stdin encoding

import sys 
import io
input_stream = io.TextIOWrapper(sys.stdin.buffer, encoding='gbk')
for line in input_stream:
    print(line)

我的问题是如何从sys.stdin 安全地读取所有文件(GBK 和 UTF-8)。或者你能给我一些更好的解决方案吗?

为了稍微扩展这个问题,我想处理这样的文件:

cat *.in | python3 handler.py

*.in 返回许多使用 UTF-8 或 GBK 编码的文件。

如果我在handler.py中使用以下代码

for line in sys.stdin:
    ...some code

它会在尝试处理 GBK 文件时立即抛出错误:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd5 in position 0: invalid continuation byte

另一方面,如果我使用这样的代码:

input_stream = io.TextIOWrapper(sys.stdin.buffer, encoding='gbk')
for line in input_stream:
    ...some code

它会在任何 UTF-8 文件上引发错误:

UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 25: illegal multibyte sequence

我想在我的脚本中找到一种安全的方式来处理这两种类型的文件(UTF-8 和 GBK)。

【问题讨论】:

  • 您需要先将每个文件作为字节流打开,窥探其中的内容以自己计算编码,然后将其关闭并使用适当的编码重新打开。
  • 对不同编码的文件使用cat *.in是有问题的,因为它会产生一个编码不一致的流,这是一个噩梦。您应该重新设计脚本以接受文件名列表,然后可以基于每个文件完成编解码器猜测,而无需检测编码更改的点。
  • 如果您有一组静态文件,请考虑使用 UTF-8 重新编码 GBK 文件。
  • @YaozongLi 您的说明非常完美!干得好。

标签: python python-3.x encoding utf-8 gbk


【解决方案1】:

您可以将输入读取为原始字节,然后检查输入以决定实际将其解码为什么。

另见Reading binary data from stdin

假设您一次可以读取整行(即整行的编码可以预期是一致的),我会尝试解码为 utf-8,然后回退到 gbk。

for raw_line in input_stream:
    try:
        line = raw_line.decode('utf-8')
    except UnicodeDecodeError:
        line = raw_line.decode('gbk')
    # ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-05
    • 1970-01-01
    相关资源
    最近更新 更多