Python не может открыть файл с неанглийскими символами в пути - PullRequest
9 голосов
/ 12 мая 2011

У меня есть файл со следующим путем: D: / bar / f レ イ ジ ー ・!! f /foo.abc

Я анализирую путь из файла XML и сохраняю его в переменной с именем pathв форме file://localhost/D:/bar/クレイジー・ヒッツ!/foo.abc Затем выполняются следующие операции:

path=path.strip()
path=path[17:] #to remove the file://localhost/  part
path=urllib.url2pathname(path)
path=urllib.unquote(path)

Ошибка:

IOError: [Errno 2] No such file or directory: 'D:\\bar\\\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xa4\xe3\x82\xb8\xe3\x83\xbc\xe3\x83\xbb\xe3\x83\x92\xe3\x83\x83\xe3\x83\x84\xef\xbc\x81\\foo.abc'

Обновление 1: я использую Python 2.7 в Windows 7

Ответы [ 3 ]

5 голосов
/ 12 мая 2011

Путь в вашей ошибке:

'\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xa4\xe3\x82\xb8\xe3\x83\xbc\xe3\x83\xbb\xe3\x83\x92\xe3\x83\x83\xe3\x83\x84\xef\xbc\x81'

Я думаю, что это версия вашего файла в кодировке UTF8.

Я создал папку с тем же именем в Windows7 ипоместил в него файл с именем 'abc.txt':

>>> a = '\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xa4\xe3\x82\xb8\xe3\x83\xbc\xe3\x83\xbb\xe3\x83\x92\xe3\x83\x83\xe3\x83\x84\xef\xbc\x81'
>>> os.listdir('.')
['?????\xb7???!']
>>> os.listdir(u'.') # Pass unicode to have unicode returned to you
[u'\u30af\u30ec\u30a4\u30b8\u30fc\u30fb\u30d2\u30c3\u30c4\uff01']
>>> 
>>> a.decode('utf8') # UTF8 decoding your string matches the listdir output
u'\u30af\u30ec\u30a4\u30b8\u30fc\u30fb\u30d2\u30c3\u30c4\uff01'
>>> os.listdir(a.decode('utf8'))
[u'abc.txt']

Таким образом, похоже, что предложение Дункана о path.decode('utf8') делает свое дело.


Обновление

Я не могу проверить это для вас, но я предлагаю вам попробовать проверить, содержит ли путь не-ascii перед выполнением .decode('utf8').Это немного бестолково ...

ASCII_TRANS = '_'*32 + ''.join([chr(x) for x in range(32,126)]) + '_'*130
path=path.strip()
path=path[17:] #to remove the file://localhost/  part
path=urllib.unquote(path)
if path.translate(ASCII_TRANS) != path: # Contains non-ascii
  path = path.decode('utf8')
path=urllib.url2pathname(path)
2 голосов
/ 12 мая 2011

Укажите имя файла в виде строки unicode для вызова open.

Как вы производите имя файла?

если указано вами как константа

Добавьте строку в начале вашего скрипта:

# -*- coding: utf8 -*-

Затем в редакторе с поддержкой UTF-8 установите для path имя файла unicode:

path = u"D:/bar/クレイジー・ヒッツ!/foo.abc"

чтение из списка содержимого каталога

Получить содержимое каталога, используя unicode dirspec:

dir_files= os.listdir(u'.')

чтение из текстового файла

Откройте файл, содержащий имя файла, используя codecs.open, чтобы прочитать unicode данные из него. Вам необходимо указать кодировку файла (поскольку вы знаете, что такое «кодировка окон по умолчанию» для приложений, не поддерживающих Юникод, на вашем компьютере).

в любом случае

Do a:

path= path.decode("utf8")

перед открытием файла; замените правильную кодировку, если не "utf8".

1 голос
/ 12 мая 2011

Вот некоторые интересные вещи из документации :

sys.getfilesystemencoding ()

Возвращает название используемой кодировки конвертировать имена файлов Unicode в имена системных файлов, или None, если используется системная кодировка по умолчанию. значение результата зависит от операционной система: в Mac OS X кодировка 'UTF-8'. В Unix кодировка предпочтения пользователя в соответствии с результат nl_langinfo (CODESET) или Нет, если nl_langinfo (CODESET) не удалось. В Windows NT + имена файлов Unicode изначально, поэтому нет преобразования выполнила. getfilesystemencoding () по-прежнему возвращает «МБК», так как это кодирование, которое должны использовать приложения когда они явно хотят преобразовать Unicode-строки в байтовые строки, которые эквивалентны при использовании в качестве файла имена. В Windows 9x кодировка 'MBCS'.

Новое в версии 2.3.

Если я правильно понимаю, вы должны передать имя файла как Unicode:

f = open(unicode(path, encoding))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...