2011-10-06 44 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

相關問題