Python的os.stat与unicode文件名

16 投票
5 回答
13652 浏览
提问于 2025-04-15 18:05

在我的Django应用中,有个用户上传了一个文件,文件名里有个Unicode字符。

当我下载文件的时候,我调用了:

os.path.exists(media)

来检查这个文件是否存在。结果,这个调用似乎又调用了

st = os.stat(path)

然后就出现了一个错误:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xcf' in position 92: ordinal not in range(128)

我该怎么解决这个问题呢?有没有什么方法可以让path.exists处理这个情况?

更新:其实,我只需要对exists的参数进行编码,也就是:

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

感谢所有回答的人。

5 个回答

2

在使用Upstart运行服务(比如gunicorn)时,出现这种错误是很常见的。

要解决这个问题,可以在Upstart的配置文件中设置环境变量:

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

这些解决方案对我都没用。不过,我找到了一种解决办法。如果你使用WSGI的话,在Apache的设置中还有另一个地方需要添加地区设置。官方文档在这里。你需要在 /etc/apache2/envvars(在Ubuntu上)添加以下两行:

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

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

9

我猜你是在用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模块来说),因为Windows的Unicode文件API是透明支持的。

撰写回答