2015-10-13 58 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'屬性。 –