Ошибка открытия файла при использовании кодека utf-8 в python - PullRequest
3 голосов
/ 15 ноября 2009

Я выполняю следующий код на Windows XP и Python 2.6.4

Но это показывает IOError.

Как открыть файл, имя которого имеет кодек utf-8.

>>> open( unicode('한글.txt', 'euc-kr').encode('utf-8') )

Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    open( unicode('한글.txt', 'euc-kr').encode('utf-8') )
IOError: [Errno 22] invalid mode ('r') or filename: '\xed\x95\x9c\xea\xb8\x80.txt'

Но следующий код для нормальной работы.

>>> open( unicode('한글.txt', 'euc-kr') )
<open file u'\ud55c\uae00.txt', mode 'r' at 0x01DD63E0>

1 Ответ

16 голосов
/ 15 ноября 2009

Интерфейс среды выполнения C, который Windows предоставляет Python, использует системную кодовую страницу для кодирования имен файлов. В отличие от OS X и современных версий Linux, в Windows системная кодовая страница никогда не является UTF-8. Таким образом, строка байтов UTF-8 не будет никакой пользы.

Вы можете закодировать имя файла для текущей кодовой страницы, используя .encode('mbcs'), что в вашем случае, вероятно, эквивалентно .encode('cp949'). Чтобы сделать его совместимым с другими платформами, где имена файлов UTF-8, вы можете поискать sys.getfilesystemencoding, что даст вам utf-8 там или mbcs в Windows.

Тем не менее, хотя cp949 будет работать для корейских символов, оно будет нарушать все, что находится за пределами репертуара этой кодовой страницы (расширенная версия EUC-KR).

Таким образом, другой подход заключается в том, чтобы сохранить ваши имена файлов как Unicode. В Windows это будет использовать собственные интерфейсы Unicode для передачи имен файлов в Windows в кодировке UTF-16LE, которую он использует внутри. (Подробнее об этой функции см. PEP277 .)

Обычно это работает и на других платформах: Linux и OS X должны молча кодировать имена файлов Unicode в UTF-8. Это может больше не работать в старых версиях Python, но это стандартный способ обработки имен файлов в Python 3 (где тип строки по умолчанию изменен на Unicode).

Ловушки, на которые нужно обратить внимание при использовании имен файлов Unicode в Python 2:

  • , если os.path.supports_unicode_filenames имеет значение False, поскольку это будет за пределами Windows, функции, которые возвращают имена файлов, такие как os.listdir, всегда будут выдавать вам байтовые строки. Вы должны обнаружить это и расшифровать их, используя sys.getfilesystemencoding.

  • если у вас есть файл в Linux / OS X с именем, которое не является допустимой строкой UTF-8, вы не сможете получить имя файла Unicode для него (UnicodeDecodeError, если вы попытаетесь). Немного угловой случай, но это может привести к надоедливым недоступным файлам.

Кстати,

open(unicode('한글.txt', 'euc-kr'))

Вероятно, вы захотите сказать 'cp949' (поскольку корейская кодовая страница Windows имеет небольшие отличия от EUC-KR). Или, в более общем смысле, 'mbcs', которая дает системную кодовую страницу, которая, вероятно, будет той же, что печатает ваша консоль. В любом случае, я не знаю о PyShell, но обычно, если вышеприведенное работает, тогда вы просто сможете набрать его напрямую:

open(u'한글')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...