首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用utf-8文件名打开文件的Python

使用utf-8文件名打开文件的Python
EN

Stack Overflow用户
提问于 2022-08-19 16:13:11
回答 2查看 357关注 0票数 0

在我的代码中,我使用了类似于file = open(path +'/'+filename, 'wb')的东西来编写文件,但是在我尝试支持非ascii文件名时,我将它编码为这样的方式。

代码语言:javascript
运行
复制
naming = path+'/'+filename
file = open(naming.encode('utf-8', 'surrogateescape'), 'wb')
write binary data...

因此,该文件命名为类似于directory/path/\xd8\xb9\xd8\xb1\xd8\xa8\xd9.txt的名称,而且它可以工作,但是当我试图再次通过以下方式获取该文件时,就会出现这样的问题:

代码语言:javascript
运行
复制
for file in path:
    data = open(file.as_posix(), 'rb)
    ...

我一直得到这个错误,'ascii' codec can't encode characters in position..,我试着把字符串转换成像data = open(bytes(file.as_posix(), encoding='utf-8'), 'rb')这样的字节,但是我得到了'utf-8' codec can't encode characters in position...'

我也尝试了file.as_posix().encode('utf-8', 'surrogateescape'),我发现编码和打印都很好,但是使用open(),我仍然得到了错误'utf-8' codec can't encode characters in position...'

如何使用utf-8文件名打开文件?

我在ubuntu上使用Python3.9

任何帮助都是非常感谢的。

编辑

我理解了为什么在编写完之后爬行到目录时会出现这个问题。因此,当我编写文件并赋予它原始字符串directory/path/\xd8\xb9\xd8\xb1\xd8\xa8\xd9.txt并将字符串编码为utf时,它写得很好。但是,当再次通过爬入目录找到文件时,str(filepath)filepath.as_posix()会以directory/path/????????.txt的形式返回字符串,所以当我试图将它编码到任何编解码器时,它会给我一个错误。

目前,我正在调查这个问题是否与我的linux区域设置有关,它被设置为POSIX,我将其更改为C.UTF-8,但仍然没有幸运的atm。

更多上下文:这是一个文件系统,文件是通过站点上传的,所以我收到utf-8格式的文件名字符串。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-08-22 12:17:16

因此,在过去几天陷入困境之后,我发现问题不在于python本身,而在于我的web框架所使用的区域设置。调试这个,我看到了

代码语言:javascript
运行
复制
import sys
print(sys.getfilesystemencoding())

返回'ASCII',这很奇怪,因为我已经将locale设置为C.UTF-8,但发现由于在Apache2上运行WSGI,我不得不在Apache配置文件中将WSGIDaemonProcess my_app locale='C.UTF-8'添加到WSGIDaemonProcess my_app locale='C.UTF-8'中,这要感谢this post.

票数 0
EN

Stack Overflow用户

发布于 2022-08-19 21:23:28

我不明白你为什么觉得你需要重新记录文件。

Linux (unix)文件名只是字节序列(有几个禁止的字节值)。没有必要在代理对中分解星体字符;星体字符的UTF-8序列在文件名中是完全可以接受的。但是创建代理项对可能会给您带来麻烦,因为代理程序没有UTF-8编码。因此,如果您实际上创建了类似于代理代码点的UTF-8编码,那么当您试图将它转换回Unicode编码点时,很可能会遇到解码错误。

不管怎么说,没必要费尽心机。在运行此会话之前,我创建了一个名为“mañana”的目录,其中包含两个空文件和。第一个是星体角色,U+1D510。正如你所看到的,一切都很好,不需要手动解码。

代码语言:javascript
运行
复制
>>> [*Path('ñ').iterdir()]
[PosixPath('ñ/'), PosixPath('ñ/mañana')]
>>> Path.mkdir('ñ2')
>>> for path in Path('ñ').iterdir():
...   open(Path('ñ2', path.name), 'w').close()
...
>>> [*Path('ñ2').iterdir()]
[PosixPath('ñ2/'), PosixPath('ñ2/mañana')]
>>> [open(path).read() for path in Path('ñ2').iterdir()] 
['', '']

注:

在一份评论中,OP说他们以前尝试过:

代码语言:javascript
运行
复制
file = open('/upload/\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a.png', 'wb')

并收到了错误

代码语言:javascript
运行
复制
UnicodeEncodeError: 'ascii' codec can't encode characters in position 8-11: ordinal not in range(128)

如果没有更多的细节,就很难知道如何应对。对于不允许非ascii字符的文件系统,open可能会引发该错误,但这在Linux上是不正常的。

但是,值得注意的是字符串文本

代码语言:javascript
运行
复制
'/upload/\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a.png'

不是你认为的那根线。Python中的\x转义是Unicode编码点(最大值为255),而不是单个UTF-8字节值。Python文字,"\xd8\xb9"包含两个字符,"O有笔画“(Ø)和”上标1“(¹);换句话说,它与字符串文字"\u00d8\u00b9"完全相同。

要获得阿拉伯字母ain (ع),只需键入它(如果您有阿拉伯键盘设置,并且源文件编码为UTF-8,这是默认的),或者对其代码点U+0639:"\u0639"使用Unicode转义。

如果您出于某种原因坚持使用显式UTF-8字节编码,则可以使用byte文字作为open的参数。

代码语言:javascript
运行
复制
file = open(b'/upload/\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a.png', 'wb')

但这是不推荐的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73419555

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档