在使用Python 2.7时,为什么我的Unicode文件名在调用file()时会引发IOError?
sys.getdefaultencoding()
Python 2.7:
我正在尝试打开一个mp3文件,以读取它的ID3标签,使用的是mutagen库(所以我不想更改方法),调用的是:
file(filename, "rb")
对于没有特殊字符的文件,这样做没问题,但有时候我似乎会遇到
IOError: [Errno 2] No such file or directory: u"somepath\\08 - Muse - I Belong To You - Mon C\x9cur S'ouvre \xc0 Ta Voix.mp3"
而其他时候
u"somepath\\02 - Max\xefmo Park - Apply Some Pressure.mp3"
则正常工作。
这两者之间有什么区别?为什么一个能工作而另一个不行呢?
谢谢,
Felix
编辑:在Eclipse的pydev下运行时,它工作正常,返回的是"Cp1252",但从命令行运行时返回的是"ascii"。当文件名打印到Eclipse控制台时是
u"somepath\\08 - Muse - I Belong To You - Mon C\u0153ur S'ouvre \xc0 Ta Voix.mp3"
编辑:从Winamp(音乐播放器)获取文件名的代码是:
winampProcess = win32api.OpenProcess(win32con.PROCESS_VM_READ, False, processID)
memoryBuffer = ctypes.create_string_buffer(256)
ctypes.windll.kernel32.ReadProcessMemory(winampProcess.handle, memoryPointer, memoryBuffer, 256, 0)
winampProcess.Close()
rawPath = win32api.GetFullPathName(memoryBuffer.raw.split("\x00")[0])
try:
unicodeString = unicode(rawPath)
except UnicodeDecodeError:
unicodeString = u""
for char in rawPath:
try:
unicodeString += unicode(char)
except UnicodeDecodeError as err:
errStr = str(err)
startIndex = errStr.index("0x")
endIndex = errStr.index(" ", startIndex)
hexStr = ""
for i in range(startIndex, endIndex):
hexStr += errStr[i]
unicodeString += unichr(int(hexStr, 16))
return unicodeString
编辑:如果我明确设置
unicode(str, "cp1252")
问题就解决了,但我仍然不明白是什么导致了这个问题,这只是一个临时的解决办法,可能对其他有问题的文件名不管用……
2 个回答
1
使用 os.listdir() 函数查看目录里的文件名,看看它是怎么编码的。然后把这个文件名和你用 filename.encode('cp1252') 得到的结果进行对比。你应该能发现两者之间的不同,这样就能知道问题出在哪里了。
我能想到的唯一真正的问题是,有些东西被解码了两次。你也可能会遇到规范化的问题,但在这种情况下,这种可能性似乎不大。
1
我猜测,你是从一个程序中获取文件名,而这个程序使用的是当前默认编码下的多字节字符集。在英文版的Windows中,默认编码是cp1252。Ascii编码不包含任何扩展字符,这就是为什么当你尝试用Ascii编码把字符串转换成Unicode时会出现错误。
补充一下:这个回答提供了一些关于在当前Windows代码页中编码文件名的信息。