在使用Python的Windows上找不到长名称的文件
我需要在Windows中浏览具有长文件名的文件夹 我尝试使用在使用Python的Windows上找不到长名称的文件,python,windows,filepath,Python,Windows,Filepath,我需要在Windows中浏览具有长文件名的文件夹 我尝试使用os.listdir(),但它会因路径名过长而崩溃,这很糟糕 我尝试使用os.walk(),但它忽略了长度超过~256的路径名,这更糟糕 我尝试了所描述的神奇的解决方法,但它只适用于映射驱动器,而不适用于 下面是一个具有短路径名的示例,它表明UNC路径名不适用于“魔术”这个词 >>> os.listdir('c:\\drivers') ['nusb3hub.cat', 'nusb3hub.inf', 'nusb3hub
os.listdir()
,但它会因路径名过长而崩溃,这很糟糕
我尝试使用os.walk()
,但它忽略了长度超过~256的路径名,这更糟糕
我尝试了所描述的神奇的解决方法,但它只适用于映射驱动器,而不适用于
下面是一个具有短路径名的示例,它表明UNC路径名不适用于“魔术”这个词
>>> os.listdir('c:\\drivers')
['nusb3hub.cat', 'nusb3hub.inf', 'nusb3hub.sys', 'nusb3xhc.cat', 'nusb3xhc.inf', 'nusb3xhc.sys']
>>> os.listdir('\\\\Uni-hq-srv6\\router')
['2009-04-0210', '2010-11-0909', ... ]
>>> mw=u'\\\\?\\'
>>> os.listdir(mw+'c:\\drivers')
[u'nusb3hub.cat', u'nusb3hub.inf', u'nusb3hub.sys', u'nusb3xhc.cat', u'nusb3xhc.inf', u'nusb3xhc.sys']
>>> os.listdir(mw+'\\\\Uni-hq-srv6\\router')
Traceback (most recent call last):
File "<pyshell#160>", line 1, in <module>
os.listdir(mw+'\\\\Uni-hq-srv6\\router')
WindowsError: [Error 123] The filename, directory name, or volume label syntax is incorrect: u'\\\\?\\\\\\Uni-hq-srv6\\router\\*.*'
结果如下:
- 数字8表示找到了所有文件
- 数字0表示它甚至没有尝试而不崩溃
- 任何介于1和7之间的数字都意味着它在中途失败而没有崩溃
- 单词
表示它崩溃了Crash
使用8.3回退以避免长路径名,在Win7资源管理器中浏览这似乎是windows本身所做的,即每个长路径都有一个较短的“真实名称”:
>>> long_unc="\\\\K53\\Users\\Tolan\\testing\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\\xxxxxxxxxxxxxxxxxxxxxxxxdddddddddddddddddddddwgggggggggggggggggggggggggggggggggggxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\\esssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggeee"
>>> os.listdir(long_unc)
FileNotFoundError: [WinError 3]
但您可以使用Win32 API(pywin32)来“构建”较短的版本,即
short_unc=win32api.GetShortPathName(win32api.GetShortPathName(win32api.GetShortPathName("\\\\K53\\Users\\Tolan\\testing\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")+"\\xxxxxxxxxxxxxxxxxxxxxxxxdddddddddddddddddddddwgggggggggggggggggggggggggggggggggggxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") + "\\esssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggeee")
>>> print(short_unc)
\\K53\Users\Tolan\testing\XXXXXX~1\XXXXXX~1\ESSSSS~1
>>> import os
>>> os.listdir(short_unc)
['test.txt']
显然,您可以将win32api.GetShortPathName调用折叠到dir探索中,而不是像我的示例中那样嵌套。
我这样做是因为如果你已经有了一个“太长”的路径,那么win32api.GetShortPathName也不会处理它,但是你可以按目录执行,并保持在限制之下。要在UNC路径上定位文件,神奇的前缀是
\?\UNC\
,而不仅仅是\?\
参考:
所以要访问//server/share/really/deep/path/etc/etc
,您需要
unicode()
构造函数)“\\?\\UNC\”
),然后“\”
(请参阅os.path.normpath()
)\\?\UNC\server\share\really\deep\path\etc\etc
我只做了一点实验(比@stenci少得多),但在Python2.7中,它似乎在os.walk()
中正常工作,而在os.listdir()中失败
警告:如果遍历的起始路径在MAX_path限制内,并且起始路径中的任何子目录都不会将其推过该限制,则它仅适用于os.walk()。这是因为as os.walk()在顶部目录中使用os.listdir()。在我之前的评论中,我说过不需要嵌套递归调用GetShortPathName
。我发现大多数时候都不需要它,但偶尔它会崩溃。我不知道是什么时候,所以我做了一个小函数,这个函数已经平稳运行了一段时间:
这是我现在使用的函数:
def short_name(name):
try:
return win32api.GetShortPathName(name)
except win32api.error:
dirname = os.path.dirname(name)
basename = os.path.basename(name)
short_dirname = win32api.GetShortPathName(dirname)
return win32api.GetShortPathName(os.path.join(short_dirname, basename))
try:
mtime = os.path.getmtime(name)
except FileNotFoundError:
name = short_name(name)
mtime = os.path.getmtime(name)
使用net use
并为UNC分配驱动器号如何?@iTayb:谢谢。这很难看,但应该有用。我需要扫描几个网络驱动器,所以我应该net-use
它们,然后net-use/delete
它们。我想知道这是在py2还是py3上,如果是py2,py3上的行为是否不同?我很久没有使用Windows了,只是好奇:会glob.glob(“*”)
为您工作?这是一个很好的问题。你能不能让标题更具描述性,这样人们在将来搜索时就更有可能找到它?类似于“在使用Python的Windows上找不到长名称的文件”的情况,看起来不需要嵌套调用。调用win32api.GetShortPathName('C:\\test\\123456789 123456789 123456789 123456789 123456789\\123456789 123456789 123456789')
返回C:\test\123456~1\123456~1
。调用short\u name(dirname)
而不是GetShortPahtName(dirname)
会是一个很好的改进吗?它会将路径分解到所需的最小值,然后添加所有剩余的位……一个重要的技巧是:如果使用Python 2.x:u'\\\\?\\UNC\\\'
short_unc=win32api.GetShortPathName(win32api.GetShortPathName(win32api.GetShortPathName("\\\\K53\\Users\\Tolan\\testing\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")+"\\xxxxxxxxxxxxxxxxxxxxxxxxdddddddddddddddddddddwgggggggggggggggggggggggggggggggggggxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") + "\\esssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggeee")
>>> print(short_unc)
\\K53\Users\Tolan\testing\XXXXXX~1\XXXXXX~1\ESSSSS~1
>>> import os
>>> os.listdir(short_unc)
['test.txt']
def short_name(name):
try:
return win32api.GetShortPathName(name)
except win32api.error:
dirname = os.path.dirname(name)
basename = os.path.basename(name)
short_dirname = win32api.GetShortPathName(dirname)
return win32api.GetShortPathName(os.path.join(short_dirname, basename))
try:
mtime = os.path.getmtime(name)
except FileNotFoundError:
name = short_name(name)
mtime = os.path.getmtime(name)