2010-01-16 3 views
12

В моем приложении Django пользователь загрузил файл с символом юникода в имени.Имена файлов Python os.stat и unicode

Когда я загрузки файлов, я звоню:

os.path.exists(media) 

, чтобы проверить, что файл существует. Это, в свою очередь, кажется, называют

st = os.stat(path) 

Который затем взрывается с ошибкой:

UnicodeEncodeError: «ASCII» кодек не может кодировать символ и «\ XCF» в позиции 92: порядковый не в (128)

Что я могу сделать? Есть ли способ path.exists для его обработки?

Обновление: На самом деле все, что мне нужно было сделать, это кодировать аргумент как существующий, т.е.

os.path.exists(media.encode('utf-8') 

Спасибо всем, кто ответил.

+2

Проблемы с вашим решением является то, что его не портативным. os.path.exists должны прозрачно обрабатывать кодировку на основе локали ОС. –

ответ

1

Кодировать кодировку файловой системы перед вызовом. См. Модуль locale.

+0

спасибо за это. Но я не уверен, что буду следовать. Вы говорите, что я могу сказать Django, что имя загруженного файла должно быть адаптировано? Я ничего не вижу об этом в модуле локали. – interstar

+2

Вы должны использовать кодировку собственной системы для обращения к файлам. Попробуйте 'locale.nl_langinfo (locale.CODESET)'. –

7

Я предполагаю, что вы в Unix. Если нет, не забудьте указать, в какой ОС вы находитесь.

Убедитесь, что ваш языковой стандарт установлен на UTF-8. Все современные Linux-системы делают это по умолчанию, обычно устанавливая переменную среды LANG на «en_US.UTF-8» или на другой язык. Кроме того, убедитесь, что ваши имена файлов закодированы в UTF-8.

С этим набором нет необходимости связываться с кодировками для доступа к файлам на любом языке, даже в Python 2.x.

[~/test] echo $LANG 
en_US.UTF-8 
[~/test] echo testing > 漢字 
[~/test] python2.6 
Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) 
[GCC 4.3.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import os 
>>> os.stat("漢字") 
posix.stat_result(st_mode=33188, st_ino=548583333L, st_dev=2049L, st_nlink=1, st_uid=1000, st_gid=1000, st_size=8L, st_atime=1263634240, st_mtime=1263634230, st_ctime=1263634230) 
>>> os.stat(u"漢字") 
posix.stat_result(st_mode=33188, st_ino=548583333L, st_dev=2049L, st_nlink=1, st_uid=1000, st_gid=1000, st_size=8L, st_atime=1263634240, st_mtime=1263634230, st_ctime=1263634230) 
>>> open("漢字").read() 
'testing\n' 
>>> open(u"漢字").read() 
'testing\n' 

Если это не сработает, запустите «locale»; если значения «C» вместо en_US.UTF-8, возможно, у вас не установлен языковой стандарт.

Если вы работаете в Windows, я думаю, что имена файлов Unicode должны всегда работать (по крайней мере, для модулей os/posix), так как API файлов Unicode в Windows поддерживается прозрачно.

+3

Я пробую то же самое с буквой ß в консоли, и это работает, но когда я выполняю его в скрипте, это не так, я получаю IOError, нет такого файла или каталога, а символ был закодирован в '\ xc3 \ x9f ' – chuse

0

Измените свой http-сервер, чтобы использовать локаль UTF-8. Например, я использую apache2 для CentOS. Я изменил /и т.д./sysconfig/HTTPd языковой стандарт по HTTPD_LANG:

# CentOS use /etc/sysconfig/httpd to config environment variables. 
# 
# By default, the httpd process is started in the C locale; to 
# change the locale in which the server runs, the HTTPD_LANG 
# variable can be set. 
# 
# HTTPD_LANG=C 
HTTPD_LANG=en_US.UTF-8 # you can change to your locale. 
+0

Это не влияет на меня (Django 1.10, работающий на Ubuntu 16.04). Я все еще получаю ошибку, и я не могу использовать решение OP, потому что я не выполняю вызов 'os.path', Django. – Deleet

+0

Конфигурация Apache может зависеть от того, какую ОС вы используете. Ubuntu может использовать другой путь. –

1

Ни одно из этих решений не работал для меня. Однако я нашел решение (a?). В настройках Apache есть еще одно место, где нужно добавить параметр локали, если вы используете WSGI. Official docs are here. Добавьте следующие две строки в /etc/apache2/envvars (на Ubuntu):

export LANG='en_US.UTF-8' 
export LC_ALL='en_US.UTF-8' 

Затем перезапустите сервер. Это решило мою проблему.

0

Легко получить такую ​​ошибку при запуске службы (например, gunicorn) от Upstart.

Чтобы исправить это, установите окр в выскочке файла:

env LANG=en_US.UTF-8 
env LC_CTYPE=en_US.UTF-8 
env LC_ALL=en_US.UTF-8 
Смежные вопросы