2015-10-13 20 views
1

问题:获取字节错误从python的UnicodeDecodeError异常偏移

  • 我有一个包含感兴趣的数据大(> 2GB)文本文件
  • 在病例> 90%,我可以假设这个数据被格式化为UTF-8或西欧式
  • 在某些罕见的情况下我有其他奇怪的编码

我试了一下:

我开始使用chardet的,但应用取得了重大的性能损失,因为它加载整个文件到内存检测它的编码之前。转念一想,也许我应该只是读了一些有代表性的数据为chardet的的检测方法,但后来意识到我有没有不缺,可能导致问题的任何随机字符(如“®”字符会导致在一个文本文件中的问题的方式,否则将解码为UTF-8就好了)。为了避免采取这种打击,除非我必须这样做,我去这条路线:

def get_file_handle(self): 
    """ 
    Default encoding is UTF-8. If that fails, try Western European (Windows-1252), else use chardet to detect 
    :return: file handle (f) 
    """ 
    try: 
     with codecs.open(self.current_file, mode='rb', encoding='utf-8') as f: 
      return f 
    except UnicodeDecodeError: 
     try: 
      with codecs.open(self.current_file, mode='rb', encoding='cp1252') as f: 
       return f 
     except UnicodeDecodeError: 
      # read raw data and detect encoding via chardet (last resort) 
      raw_data = open(self.current_file, 'r').read() 
      result = chardet.detect(raw_data) 
      char_enc = result['encoding'] 
      with codecs.open(self.current_file, mode='rb', encoding=char_enc) as f: 
       return f 

虽然这工作,在极少数情况下达到第三/最例外,它仍然是整个文件读取到内存中。简单阅读一些随机代表性数据可能会错过文本文档中的违规字符。这是我想要做什么:

  • 当我拿到的UnicodeDecodeError,追溯的最后一行是:

    UnicodeDecodeError: 'utf8' codec can't decode byte 0xae in position 2867043: invalid start byte

  • 我想获得的字节偏移( 0xae),然后抓住1.000字符之前和从该文件后,供给到chardet模块进行检测,因此包括有问题的字符和其它的数据立足于编码预测。

我已经知道如何读取的块数据(但随意添加这太),主要是我感兴趣的如何获得字节从回溯偏移。

+0

为什么不使用'codecs.IncrementalDecoder'和饲料它的文件块在同一时间? –

+0

@ IgnacioVazquez - 艾布拉姆斯我当然可以这样做,但我宁愿不喂养它的一切。如果我已经知道错误在哪里,我想用一些前后的上下文为它提供该字符(除非我误解了你)。 –

回答

1

如何:

except UnicodeDecodeError as e: 
    # read raw data and detect encoding via chardet (last resort) 
    with open(self.current_file, 'r') as f: 
     f.seek(e.start - 1000) 
     raw_data = f.read(2000) 
     result = chardet.detect(raw_data) 
     ... 
+0

所以要澄清,'e.start'将返回字节偏移问题发生在哪里?在文档中我找不到任何关于此的信息。你能提供一个链接,以便我可以了解更多信息吗?谢谢, –

+0

我从来没有发现任何实际的文件或者,我只是猜测和推断。我建议尝试用代码来反驳它。如果你对此不满意,那么可以用正则表达式解析消息。请注意,还有一个'end'属性。 –