【问题标题】:How to read multiple known file encodings如何读取多个已知文件编码
【发布时间】:2019-04-06 16:42:22
【问题描述】:

我一直在网上搜索解决读取具有不同编码的文件的解决方案,并且我发现了许多“无法分辨文件的编码是什么”的实例(因此,如果有人正在阅读此内容并有链接我会很感激)。但是,我正在处理的问题比“打开任何文件编码”更集中,而是打开一组已知的编码。我绝不是这个主题的专家,但我想我会发布我的解决方案,以防有人遇到这个问题。

具体例子:

已知的文件编码:utf8 和 windows ansi

初始问题:据我所知,没有为 python 的 open('file', 'r') 命令指定编码自动默认为 encoding='utf8' 当尝试 f.readline() ansi 文件时,在运行时引发了 UnicodeDecodeError。对此的常见搜索是:“UnicodeDecodeError: 'utf-8' codec can't decode byte”

次要问题:所以我想好吧,很简单,我们知道引发的异常,因此请阅读一行,如果它引发此 UnicodeDecodeError 然后关闭文件并使用 open('file', 'r', encoding='ansi') 重新打开它。这样做的问题是,有时 utf8 能够很好地读取 ansi 编码文件的前几行,但在后面的行中却失败了。现在解决方案变得清晰了;我必须用 utf8 通读整个文件,如果失败了,我就知道这个文件是 ansi。

我将对此发表我的看法作为答案,但如果有人有更好的解决方案,我也将不胜感激:)

【问题讨论】:

  • "Windows ANSI" 用词不当,而且定义不完全。您可能是指代码页 1252。
  • 在混合编码的文件中解决这个问题有很多问题。如果您了解 UTF-8 的设计方式,则在遇到解码错误时回退到 Latin-1(或 CP1252 或其他)是众所周知且相当简单的技术。
  • 您好,tripleee,感谢您的回复。我查看了您的链接,在我看来它是一组特定的字符修复。就我而言,我不知道文件中使用了哪些字符。答案似乎也更高级一些,对于可能不明白为什么他们通常的读取文件不起作用的初学者来说,我发布的答案似乎更简单
  • 这很不幸。顺便说一句——Notepad++ 是在猜测(如果它说“ANSI”,那么它的报告信息就不是很丰富。)

标签: python python-3.x character-encoding


【解决方案1】:
f = open(path, 'r', encoding='utf8')
while True:
    try:
        line = f.readline()
    except UnicodeDecodeError:
        f.close()
        encodeing = 'ansi'
        break
    if not line:
        f.close()
        encoding = 'utf8'
        break

# now open your file for actual reading and data handling
with open(path, 'r', encoding=encoding) as f:

【讨论】:

    【解决方案2】:

    如果把linke问题中的codec替换成tripleee,就是

    import codecs
    
    last_position = -1
    
    def mixed_decoder(unicode_error):
        global last_position
        string = unicode_error[1]
        position = unicode_error.start
        if position <= last_position:
            position = last_position + 1
        last_position = position
        new_char = string[position].decode("ansi")
        #new_char = u"_"
        return new_char, position + 1
    
    codecs.register_error("mixed", mixed_decoder)
    

    奖励:在发生错误之前读取为 UTF-8,并且不需要就地错误处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-20
      • 1970-01-01
      • 1970-01-01
      • 2018-03-05
      • 2019-04-05
      • 2012-08-13
      • 1970-01-01
      相关资源
      最近更新 更多