在Windows环境下管理Mac OS创建的非ASCII字符文件名?

5 投票
1 回答
1650 浏览
提问于 2025-04-17 03:50

我正在处理一大堆未知文件,并且一直在学习Python,以帮助我过滤、排序和管理这些文件。

我正在查看的这个文件集合中,有很多资源分叉,我写了一个小脚本来找到它们并删除它们(下一步是找到它们并移动它们,但那是以后的事)。

在这个集合中,我发现有一些文件名中包含非ASCII字符,这似乎导致了os.delete函数出错。

举个例子,文件名是: ._spec com report 395 (注意,3的下面有一个小点,我找不到示例,也不知道怎么显示这个文件名的十六进制...)

我记录了所有的文件名,日志中记录的这个文件是: ._spec com report 3?95

我遇到的错误是一个窗口错误,因为它找不到这个文件(传递的字符串与Windows操作系统中识别的文件名不一致)。我加了一个try语句来绕过这个问题,但我真的想好好解决它。

我还尝试在walk选项中使用unicode开关 `os.walk(u'.')`,参考了这个帖子: 处理Python字符串中的ASCII字符(最佳答案),但我遇到了以下错误:

Traceback (most recent call last):
 File "<stdin>", line 3, in <module>
 File "c:\python27\lib\encodings\cp850.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode character u'\uf022' in position
20: character maps to <undefined>

所以我猜问题出在文件名的解析上,不知道有没有人能给我指个方向...

代码:

import os
import sys

rootdir = "c:\target Dir to walk"
destKeep = "Keepers.txt"
destDelete = "Deleted.txt"

matchingText = "._"
files_removed = 1
for folder, subs, files in os.walk(rootdir):  
    outfileKeep = open(destKeep,"a")
    outfileDelete = open(destDelete,"a")
    for filename in files:
        matchScore = filename.find(matchingText)
        src = os.path.join(folder, filename)
        srcNewline = src + ", " + str(filename) + "\n"
        if matchScore == -1:
        outfileKeep.writelines(srcNewline)
        else: 
            outfileDelete.writelines(srcNewline)
            try:
                os.remove(src)
        except WindowsError:
                print "I was unable to delete this file:"
                outfileKeep.writelines(srcNewline)
            files_removed += 1
            if files_removed:
                print '%d files removed' % files_removed
            else :
                print 'No files removed'
    outfileKeep.close()
    outfileDelete.close()

1 个回答

3

os.walk(u'.') 是获取本地Unicode文件名的常用方法,通常是没问题的;我用的时候也没遇到问题。

你的问题出在这里:

srcNewline = src + ", " + str(filename) + "\n"

str(filename) 会使用默认的编码方式把你的Unicode字符串转换成字节,而这个编码方式不支持字符U+F022(*),所以你会遇到 UnicodeEncodeError 错误。你需要选择一个编码格式来存储到输出文件中,比如可以这样写 srcNewLine= '%s, %s\n' % (src, filename.encode('utf-8')),或者(可能更好)保持你的字符串为Unicode格式,并使用 codecs.open 打开文件来写入。

(*: 这个字符是一个私用区域的字符,不应该使用,不过现在也没什么办法了,我想……)

撰写回答