Python 无法打开路径中包含非英文字符的文件

发布于 2024-11-07 05:29:55 字数 601 浏览 0 评论 0原文

我有一个具有以下路径的文件:D:/bar/kureeiジー・ヒッツ!/foo.abc

我正在解析 XML 文件中的路径并将其以以下形式存储在名为 path 的变量中file://localhost/D:/bar/kureeiジー・ヒッツ!/foo.abc 然后,正在执行以下操作:

path=path.strip()
path=path[17:] #to remove the file://localhost/  part
path=urllib.url2pathname(path)
path=urllib.unquote(path)

错误是:

IOError: [Errno 2] No such file or directory: 'D:\\bar\\\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xa4\xe3\x82\xb8\xe3\x83\xbc\xe3\x83\xbb\xe3\x83\x92\xe3\x83\x83\xe3\x83\x84\xef\xbc\x81\\foo.abc'

I am using Python 2.7 on Windows 7

I have a file with the following path : D:/bar/クレイジー・ヒッツ!/foo.abc

I am parsing the path from a XML file and storing it in a variable called path in the form of file://localhost/D:/bar/クレイジー・ヒッツ!/foo.abc
Then, the following operations are being done:

path=path.strip()
path=path[17:] #to remove the file://localhost/  part
path=urllib.url2pathname(path)
path=urllib.unquote(path)

The error is:

IOError: [Errno 2] No such file or directory: 'D:\\bar\\\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xa4\xe3\x82\xb8\xe3\x83\xbc\xe3\x83\xbb\xe3\x83\x92\xe3\x83\x83\xe3\x83\x84\xef\xbc\x81\\foo.abc'

I am using Python 2.7 on Windows 7

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

鸢与 2024-11-14 05:29:55

您的错误中的路径是:

'\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xa4\xe3\x82\xb8\xe3\x83\xbc\xe3\x83\xbb\xe3\x83\x92\xe3\x83\x83\xe3\x83\x84\xef\xbc\x81'

我认为这是您的文件名的 UTF8 编码版本。

我在 Windows7 上创建了一个同名的文件夹,并在其中放置了一个名为“abc.txt”的文件:

>>> a = '\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xa4\xe3\x82\xb8\xe3\x83\xbc\xe3\x83\xbb\xe3\x83\x92\xe3\x83\x83\xe3\x83\x84\xef\xbc\x81'
>>> os.listdir('.')
['?????\xb7???!']
>>> os.listdir(u'.') # Pass unicode to have unicode returned to you
[u'\u30af\u30ec\u30a4\u30b8\u30fc\u30fb\u30d2\u30c3\u30c4\uff01']
>>> 
>>> a.decode('utf8') # UTF8 decoding your string matches the listdir output
u'\u30af\u30ec\u30a4\u30b8\u30fc\u30fb\u30d2\u30c3\u30c4\uff01'
>>> os.listdir(a.decode('utf8'))
[u'abc.txt']

所以看来 Duncan 的 path.decode('utf8') 建议可以解决问题。


更新

我无法为您测试这一点,但我建议您在执行.decode('utf8')之前尝试检查路径是否包含非ascii。这有点hacky...

ASCII_TRANS = '_'*32 + ''.join([chr(x) for x in range(32,126)]) + '_'*130
path=path.strip()
path=path[17:] #to remove the file://localhost/  part
path=urllib.unquote(path)
if path.translate(ASCII_TRANS) != path: # Contains non-ascii
  path = path.decode('utf8')
path=urllib.url2pathname(path)

The path in your error is:

'\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xa4\xe3\x82\xb8\xe3\x83\xbc\xe3\x83\xbb\xe3\x83\x92\xe3\x83\x83\xe3\x83\x84\xef\xbc\x81'

I think this is the UTF8 encoded version of your filename.

I've created a folder of the same name on Windows7 and placed a file called 'abc.txt' in it:

>>> a = '\xe3\x82\xaf\xe3\x83\xac\xe3\x82\xa4\xe3\x82\xb8\xe3\x83\xbc\xe3\x83\xbb\xe3\x83\x92\xe3\x83\x83\xe3\x83\x84\xef\xbc\x81'
>>> os.listdir('.')
['?????\xb7???!']
>>> os.listdir(u'.') # Pass unicode to have unicode returned to you
[u'\u30af\u30ec\u30a4\u30b8\u30fc\u30fb\u30d2\u30c3\u30c4\uff01']
>>> 
>>> a.decode('utf8') # UTF8 decoding your string matches the listdir output
u'\u30af\u30ec\u30a4\u30b8\u30fc\u30fb\u30d2\u30c3\u30c4\uff01'
>>> os.listdir(a.decode('utf8'))
[u'abc.txt']

So it seems that Duncan's suggestion of path.decode('utf8') does the trick.


Update

I can't test this for you, but I suggest that you try checking whether the path contains non-ascii before doing the .decode('utf8'). This is a bit hacky...

ASCII_TRANS = '_'*32 + ''.join([chr(x) for x in range(32,126)]) + '_'*130
path=path.strip()
path=path[17:] #to remove the file://localhost/  part
path=urllib.unquote(path)
if path.translate(ASCII_TRANS) != path: # Contains non-ascii
  path = path.decode('utf8')
path=urllib.url2pathname(path)
泛滥成性 2024-11-14 05:29:55

将文件名作为 unicode 字符串提供给 open 调用。

你如何产生文件名?

如果您提供为常量,则

在脚本开头附近添加一行:

# -*- coding: utf8 -*-

然后,在支持 UTF-8 的编辑器中,将 path 设置为 unicode 文件名:

path = u"D:/bar/クレイジー・ヒッツ!/foo.abc"

从目录内容列表

使用 unicode dirspec 检索目录内容:

dir_files= os.listdir(u'.')

从文本文件中读取

使用 codecs.open 打开包含文件名的文件来读取 unicode 数据来自 它。您需要指定文件的编码(因为您知道计算机上非 Unicode 应用程序的“默认 Windows 字符集”是什么)。

无论如何,

请执行以下操作:

path= path.decode("utf8")

在打开文件之前;如果不是“utf8”,请替换正确的编码。

Provide the filename as a unicode string to the open call.

How do you produce the filename?

if provided as a constant by you

Add a line near the beginning of your script:

# -*- coding: utf8 -*-

Then, in a UTF-8 capable editor, set path to the unicode filename:

path = u"D:/bar/クレイジー・ヒッツ!/foo.abc"

read from a list of directory contents

Retrieve the contents of the directory using a unicode dirspec:

dir_files= os.listdir(u'.')

read from a text file

Open the filename-containing-file using codecs.open to read unicode data from it. You need to specify the encoding of the file (because you know what is the “default windows charset” for non-Unicode applications on your computer).

in any case

Do a:

path= path.decode("utf8")

before opening the file; substitute the correct encoding if not "utf8".

池木 2024-11-14 05:29:55

以下是文档中的一些有趣内容:

sys.getfilesystemencoding()

返回所用编码的名称
将 Unicode 文件名转换为
系统文件名,或者 None 如果
使用系统默认编码。这
结果值取决于操作
系统:在 Mac OS X 上,编码为
'utf-8'。在 Unix 上,编码是
根据用户的偏好
nl_langinfo(CODESET) 的结果,或
如果 nl_langinfo(CODESET) 则无
失败的。在 Windows NT+ 上,文件名是
原生 Unicode,因此无需转换
执行。获取文件系统编码()
仍然返回“mbcs”,因为这是
应用程序应使用的编码
当他们明确想要转换时
Unicode 字符串到字节字符串
用作文件时是等效的
名称。在 Windows 9x 上,编码为
“mbc”。

2.3 版本中的新增功能。

如果我理解正确,您应该将文件名作为 unicode 传递:

f = open(unicode(path, encoding))

Here's some interesting stuff from the documentation:

sys.getfilesystemencoding()

Return the name of the encoding used
to convert Unicode filenames into
system file names, or None if the
system default encoding is used. The
result value depends on the operating
system: On Mac OS X, the encoding is
'utf-8'. On Unix, the encoding is the
user’s preference according to the
result of nl_langinfo(CODESET), or
None if the nl_langinfo(CODESET)
failed. On Windows NT+, file names are
Unicode natively, so no conversion is
performed. getfilesystemencoding()
still returns 'mbcs', as this is the
encoding that applications should use
when they explicitly want to convert
Unicode strings to byte strings that
are equivalent when used as file
names. On Windows 9x, the encoding is
'mbcs'.

New in version 2.3.

If I understand this correctly, you should pass the file name as unicode:

f = open(unicode(path, encoding))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文