在我的代码中,我使用了类似于file = open(path +'/'+filename, 'wb')
的东西来编写文件,但是在我尝试支持非ascii文件名时,我将它编码为这样的方式。
naming = path+'/'+filename
file = open(naming.encode('utf-8', 'surrogateescape'), 'wb')
write binary data...
因此,该文件命名为类似于directory/path/\xd8\xb9\xd8\xb1\xd8\xa8\xd9.txt
的名称,而且它可以工作,但是当我试图再次通过以下方式获取该文件时,就会出现这样的问题:
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格式的文件名字符串。
发布于 2022-08-22 12:17:16
因此,在过去几天陷入困境之后,我发现问题不在于python本身,而在于我的web框架所使用的区域设置。调试这个,我看到了
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.。
发布于 2022-08-19 21:23:28
我不明白你为什么觉得你需要重新记录文件。
Linux (unix)文件名只是字节序列(有几个禁止的字节值)。没有必要在代理对中分解星体字符;星体字符的UTF-8序列在文件名中是完全可以接受的。但是创建代理项对可能会给您带来麻烦,因为代理程序没有UTF-8编码。因此,如果您实际上创建了类似于代理代码点的UTF-8编码,那么当您试图将它转换回Unicode编码点时,很可能会遇到解码错误。
不管怎么说,没必要费尽心机。在运行此会话之前,我创建了一个名为“mañana
”的目录,其中包含两个空文件和。第一个是星体角色,U+1D510。正如你所看到的,一切都很好,不需要手动解码。
>>> [*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说他们以前尝试过:
file = open('/upload/\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a.png', 'wb')
并收到了错误
UnicodeEncodeError: 'ascii' codec can't encode characters in position 8-11: ordinal not in range(128)
如果没有更多的细节,就很难知道如何应对。对于不允许非ascii字符的文件系统,open
可能会引发该错误,但这在Linux上是不正常的。
但是,值得注意的是字符串文本
'/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
的参数。
file = open(b'/upload/\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a.png', 'wb')
但这是不推荐的。
https://stackoverflow.com/questions/73419555
复制相似问题