Python os.stat和unicode文件名

时间:2010-01-16 08:30:47

标签: python unicode operating-system

在我的Django应用程序中,用户上传了名称中带有unicode字符的文件。

当我下载文件时,我正在打电话:

os.path.exists(media)

测试文件是否存在。反过来,这似乎叫

st = os.stat(path)

然后会出现错误:

UnicodeEncodeError:'ascii'编解码器无法对位置92中的字符u'\ xcf'进行编码:序数不在范围内(128)

我该怎么办?是否有path.exists可以选择处理它?<​​/ p>

更新:实际上,我所要做的就是将参数编码为exists,即

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

谢谢所有回答的人。

5 个答案:

答案 0 :(得分:8)

我假设你在Unix中。如果没有,请记得说出你所在的操作系统。

确保您的区域设置设置为UTF-8。默认情况下,所有现代Linux系统都会这样做,通常是将环境变量LANG设置为“en_US.UTF-8”或其他语言。另外,请确保您的文件名以UTF-8编码。

使用该集合,即使在Python 2.x中,也无需使用任何语言来编码文件,即使在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模块),因为Windows中的Unicode文件API是透明支持的。

答案 1 :(得分:4)

这些解决方案都不适合我。但是,我确实找到了(a?)解决方案。在Apache设置中还有另一个地方,如果使用WSGI,则必须添加语言环境设置。 Official docs are here。将以下两行添加到/etc/apache2/envvars(在Ubuntu上):

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

然后重启服务器。这解决了我的问题。

答案 2 :(得分:2)

在调用之前编码到文件系统编码。请参阅locale模块。

答案 3 :(得分:1)

将您的http服务器更改为使用UTF-8语言环境。例如,我在CentOS上使用apache2。我通过HTTPD_LANG更改了 / etc / sysconfig / httpd 区域设置:

# 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.

答案 4 :(得分:1)

从Upstart运行服务(例如:gunicorn)时很容易出现这种错误。

要解决此问题,请在upstart文件中设置env:

env LANG=en_US.UTF-8
env LC_CTYPE=en_US.UTF-8
env LC_ALL=en_US.UTF-8