Используя python 2.7, почему мое имя файла Unicode вызывает IOError при вызове file () для него? - PullRequest
1 голос
/ 12 января 2011

Python 2.7:

Я пытаюсь открыть mp3, чтобы прочитать его тег ID3, используя мутаген (так что я бы предпочел не менять метод), который вызывает:

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

РЕДАКТИРОВАТЬ: Он работал при запуске под pydev в Eclipse, для которого

sys.getdefaultencoding()

вернул "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 голос
/ 17 января 2011

Просто угадайте - вы извлекаете имя файла из программы, которая использует многобайтовый набор символов в текущей кодировке по умолчанию, которая является cp1252 для английских версий Windows. Ascii не содержит любых расширенных символов, поэтому вы получаете сообщение об ошибке при попытке кодировать строку в Unicode с использованием кодировки Ascii.

Редактировать: этот ответ содержит некоторую информацию о кодировании имен файлов в текущей кодовой странице Windows.

1 голос
/ 12 января 2011

Используйте os.listdir () в каталоге, чтобы увидеть, какое имя файла закодировано.Затем сравните это с тем, что вы получаете, когда вы делаете filename.encode ('cp1252').Должна быть разница, и это должно сказать вам, что не так.

Единственная реальная проблема, о которой я могу думать, это то, что что-то декодируется дважды.У вас тоже могут быть проблемы с нормализацией, но в этом случае это маловероятно.

...