在Windows中,如何使用Python复制“临时 Internet 文件”夹中的文件
我正在使用这段代码来递归查找一个文件夹中的文件,要求文件大小大于50000字节。
def listall(parent):
lis=[]
for root, dirs, files in os.walk(parent):
for name in files:
if os.path.getsize(os.path.join(root,name))>500000:
lis.append(os.path.join(root,name))
return lis
这个方法运行得很好。可是当我在Windows的“临时互联网文件”文件夹中使用它时,出现了一个错误。
Traceback (most recent call last):
File "<pyshell#4>", line 1,
in <module> listall(a) File "<pyshell#2>",
line 5, in listall if os.path.getsize(os.path.join(root,name))>500000:
File "C:\Python26\lib\genericpath.py", line 49, in getsize return os.stat(filename).st_size WindowsError: [Error 123] The filename, directory name, or volume label syntax is incorrect: 'C:\\Documents and Settings\\khedarnatha\\Local Settings\\Temporary Internet Files\\Content.IE5\\EDS8C2V7\\??????+1[1].jpg'
我觉得这可能是因为Windows在这个特定的文件夹中给文件命名时使用了特殊字符……请帮我解决这个问题。
1 个回答
3
这是因为保存的文件名‘(something)+1[1].jpg’里面有一些非ASCII字符,也就是那些不符合‘系统默认编码’的字符(有时也被误称为‘ANSI’)。
像Python这样的程序使用的是基于字节的C标准库(stdio
)来访问文件,这就导致它们在处理Unicode文件名时会遇到很大的问题。在其他平台上,它们可以直接使用UTF-8编码,大家都能愉快地使用,但在Windows上,系统默认编码从来不是UTF-8,所以总会有一些字符无法用当前的编码表示。这些字符会被替换成?
或者其他看起来相似的字符,当你尝试读取这些名字被搞乱的文件时,就会出现像上面那样的错误。
你得到的编码页面取决于你的地区设置:在西方的Windows安装中,它通常是cp1252(类似于ISO-8859-1,也叫‘Latin-1’),所以你只能使用这些字符。
幸运的是,比较新的Python版本(2.3及以上,根据PEP277)可以通过使用原生的Win32 API来直接支持Unicode文件名,而不是使用stdio。如果你把一个Unicode字符串传给os.listdir()
,Python会使用这些原生的Unicode API,这样你就能得到包含原始字符的文件名,而不是那些被搞乱的字符。所以如果你用Unicode路径调用listall
:
listall(ur'C:\Documents and Settings\khedarnatha\Local Settings\Temporary Internet Files')
它应该能正常工作。