2011-10-06 32 views
4

我处理大量未知文件的集合,并一直在学习python来帮助我过滤/排序和以其他方式缠绕这些文件。在Windows环境中管理Mac OS创建的非ASCII字符的文件名?

我正在看的一个集合有大量的资源分支,我写了一个脚本来找到它们,并删除它们(下一步是找到它们,然后移动它们,但那是另一天)。

我在这个集合中发现有多个文件在文件名中没有ascii字符,这似乎是在跳过os.delete函数。

示例文件名:._spec COM报告395 (NB 3有它的下面有一个小圆点,我无法找到一个例子,或找出如何显示文件名的十六进制...)

我记录所有的文件名,这是该文件的日志记录:?._spec COM报告3 95

我得到的错误是一个windowserror,因为它无法找到该文件(字符串它的消逝并不是Windows OS所知道的文件)。我在try子句中允许我使用rounf,但我真的很想正确处理它。

我也使用Unicode的开关在行走选项`os.walk试图按照这个帖子(U“”):Handling ascii char in python string(上回答)我看到以下错误:

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() 

回答

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 ed文件将它们写入文件来选择要在输出文件中存储哪种编码。

(*:这是一个不应使用的专用区的性格,但你可以做的不多,现在我猜...)

+0

嘿,感谢您的答复。我理解你所说的大部分内容,并一直在玩弄你的建议。我仍然无法实现它 - 我认为我更接近理解问题......问题似乎是操作系统层如何处理文件名,这与基于MSDOS的函数的工作方式不同文件名。基本上,文件名(未知编码)中有一个2字节的字符,该资源管理器可以'看到'但被剥离并被屏蔽了MSDOS。看起来这个角色的传递是问题 - 也许我应该看一个比特流而不是一个字符串? – Jay

+0

我做了一个快速截图,试图描述一下:http://imgur.com/kBVSa – Jay

+0

我还发现有问题的字形包含一个ASCII码,后面跟着一个十六进制代码EF 80 A2。我通过查看Firefox中的文件夹并查看源代码发现了这一点。有趣的是,我可以看到几个数字的数字字形,每个数字都有相同的下面的代码,为字符建议一个4字节的字 - UTF-16? – Jay

相关问题