12

Пытаюсь читать файл портов от IANA. Он сохранен в кодировке UTF-8 w/o BOM. Но на одной из строк функция readline() ругается вот таким вот образом

'charmap' codec can't decode byte 0x98 in position 7938: character maps to <"undefined">

Строка в файле выглядит следующим образом:

# Jim Harlan <"jimh&infowest.com">

Какой костыль придумать для этого? Или есть прямой путь решения?

UPD

Ибо костыль в виде удаления данной строки пойдет (причем она, почему-то вот такая одна), но только на время отладки, ибо потом вдруг что, партнеры будут рвать волосы на моей голове. Так же выложу код, которым пользуюсь для данной операции:

try:
    file = open(path, 'r')
    while True:
        line = file.readline()
        if(not line):
            break
        print(line)
finally:
    file.close()
rnd_d
  • 2,485
  • 19
  • 25
Dex
  • 9,981
  • 3
  • 34
  • 60

4 Answers4

9

попробуйте использовать встроенную библиотеку codecs:

import codecs
fileObj = codecs.open( "someFilePath", "r", "utf_8_sig" )
text = fileObj.read() # или читайте по строке
fileObj.close()
rnd_d
  • 2,485
  • 19
  • 25
  • Так ошибка нашлась еще раньше:

    'charmap' codec can't encode characters in position 29-30: character maps to >

    – Dex Sep 18 '11 at 22:00
  • Добавил в вопрос некоторые поправки. – Dex Sep 19 '11 at 00:02
  • 1
    для utf-8 с BOM нужно поменять encoding в open() на "utf_8_sig" – rnd_d Sep 19 '11 at 07:44
  • Пишет, что он без BOM. Хм, а последняя версия вообще другого формата и в ANSI, дурдом – Dex Sep 19 '11 at 08:22
  • проблема решилась или вы случайно пометили мой ответ? – rnd_d Sep 20 '11 at 08:04
  • 1
    Можно сказать, что 50/50. Проблема с первым файлом решилась удалением злополучной строки. Новый файл в другом формате. Поэтому, пожалуй вы правы, это была случайный всплеск радости. Но плюсик ваш:) – Dex Sep 20 '11 at 20:25
  • 1
    Не используйте codecs, который может некорректно работать с режимом универсальных строк. Вместо этого io.open() можно использовать. – jfs Nov 16 '16 at 22:17
9

Чтобы прочитать текстовый файл, закодированный с использованием utf-8 кодировки в Питоне, можно использовать io.open() функцию, которая доступна как встроенная open() в Питоне 3:

#!/usr/bin/env python
import io

with io.open(path, encoding='utf-8') as file:
    for line in file:
        process(line)

Если в файле возможны ошибки, связанные с кодировкой: сама кодировка верна, но могут быть мелкие погрешности, тогда можно передать errors='ignore' обработчик ошибок (или другое значение в зависимости от конкретной ситуации).

Не используйте codecs, который может некорректно работать с режимом универсальных строк.
Не нужно менять вашу кодовую страницу на cp65001, чтобы utf-8 файл прочитать.
Если хотите напечатать Unicode в Виндовую консоль, то см. Как из Python вывести на Windows-консоль строку в Юникоде?

jfs
  • 52,361
2

Постоянно ловил эту ошибку, раз за разом. Решение увидел здесь.

import codecs
file = codecs.open( "yourFile", "r", "utf-8" )
data = file.read()
file .close()
  • chcp 65001 в командной строке

Этими не сложными действиями проблема решена.

1
file = codecs.open(path, encoding='utf-8', mode='r')
Ali
  • 2,140
  • 10
  • 10