ste*_*nci 30 python windows filepath
我需要在Windows中浏览具有长文件名的文件夹.
我尝试使用os.listdir()
,但它崩溃了很长的路径名,这很糟糕.
我试过使用os.walk()
,但它忽略了长于~256的路径名,这更糟糕.
我尝试了这里描述的魔术解决方法,但它只适用于映射驱动器,而不适用于UNC路径名.
下面是一个使用短路径名的示例,它显示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\\*.*'
Run Code Online (Sandbox Code Playgroud)
关于如何处理长路径名或使用unicode UNC路径名的任何想法?
编辑:
根据以下评论的建议,我创建了一些测试函数来比较Python 2.7和3.3,并添加了测试glob.glob
和os.listdir
之后的测试os.chdir
.
os.chdir
没有像预期的那样有帮助(见本评论).
这glob.glob
是Python 3.3中唯一能够更好地工作的,但仅限于一种情况:使用魔术字和驱动器名称.
这是我使用的代码(它适用于2.7和3.3).我现在正在学习Python,我希望这些测试有意义:
from __future__ import print_function
import os, glob
mw = u'\\\\?\\'
def walk(root):
n = 0
for root, dirs, files in os.walk(root):
n += len(files)
return n
def walk_mw(root):
n = 0
for root, dirs, files in os.walk(mw + root):
n += len(files)
return n
def listdir(root):
try:
folders = [f for f in os.listdir(root) if os.path.isdir(os.path.join(root, f))]
files = [f for f in os.listdir(root) if os.path.isfile(os.path.join(root, f))]
n = len(files)
for f in folders:
n += listdir(os.path.join(root, f))
return n
except:
return 'Crash'
def listdir_mw(root):
if not root.startswith(mw):
root = mw + root
try:
folders = [f for f in os.listdir(root) if os.path.isdir(os.path.join(root, f))]
files = [f for f in os.listdir(root) if os.path.isfile(os.path.join(root, f))]
n = len(files)
for f in folders:
n += listdir_mw(os.path.join(root, f))
return n
except:
return 'Crash'
def listdir_cd(root):
try:
os.chdir(root)
folders = [f for f in os.listdir('.') if os.path.isdir(os.path.join(f))]
files = [f for f in os.listdir('.') if os.path.isfile(os.path.join(f))]
n = len(files)
for f in folders:
n += listdir_cd(f)
return n
except:
return 'Crash'
def listdir_mw_cd(root):
if not root.startswith(mw):
root = mw + root
try:
os.chdir(root)
folders = [f for f in os.listdir('.') if os.path.isdir(os.path.join(f))]
files = [f for f in os.listdir('.') if os.path.isfile(os.path.join(f))]
n = len(files)
for f in folders:
n += listdir_cd(f) # the magic word can only be added the first time
return n
except:
return 'Crash'
def glb(root):
folders = [f for f in glob.glob(root + '\\*') if os.path.isdir(os.path.join(root, f))]
files = [f for f in glob.glob(root + '\\*') if os.path.isfile(os.path.join(root, f))]
n = len(files)
for f in folders:
n += glb(os.path.join(root, f))
return n
def glb_mw(root):
if not root.startswith(mw):
root = mw + root
folders = [f for f in glob.glob(root + '\\*') if os.path.isdir(os.path.join(root, f))]
files = [f for f in glob.glob(root + '\\*') if os.path.isfile(os.path.join(root, f))]
n = len(files)
for f in folders:
n += glb_mw(os.path.join(root, f))
return n
def test():
for txt1, root in [('drive ', r'C:\test'),
('UNC ', r'\\Uni-hq-srv6\router\test')]:
for txt2, func in [('walk ', walk),
('walk magic word ', walk_mw),
('listdir ', listdir),
('listdir magic word ', listdir_mw),
('listdir cd ', listdir_cd),
('listdir magic word cd ', listdir_mw_cd),
('glob ', glb),
('glob magic word ', glb_mw)]:
print(txt1, txt2, func(root))
test()
Run Code Online (Sandbox Code Playgroud)
这是结果:
Crash
意味着它崩溃了-
Python 2.7
drive walk 5
drive walk magic word 8 * GOOD *
drive listdir Crash
drive listdir magic word 8 * GOOD *
drive listdir cd Crash
drive listdir magic word cd 5
drive glob 5
drive glob magic word 0
UNC walk 6
UNC walk magic word 0
UNC listdir 5
UNC listdir magic word Crash
UNC listdir cd 5
UNC listdir magic word cd Crash
UNC glob 5
UNC glob magic word 0
Python 3.3
drive walk 5
drive walk magic word 8 * GOOD *
drive listdir Crash
drive listdir magic word 8 * GOOD *
drive listdir cd Crash
drive listdir magic word cd 5
drive glob 5
drive glob magic word 8 * GOOD *
UNC walk 6
UNC walk magic word 0
UNC listdir 5
UNC listdir magic word Crash
UNC listdir cd 5
UNC listdir magic word cd Crash
UNC glob 5
UNC glob magic word 0
Run Code Online (Sandbox Code Playgroud)
使用8.3后备来避免长路径名,在Win7资源管理器中浏览这似乎是Windows本身所做的,即每个长路径都有一个较短的'真实名称':
>>> long_unc="\\\\K53\\Users\\Tolan\\testing\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\\xxxxxxxxxxxxxxxxxxxxxxxxdddddddddddddddddddddwgggggggggggggggggggggggggggggggggggxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\\esssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggeee"
>>> os.listdir(long_unc)
FileNotFoundError: [WinError 3]
Run Code Online (Sandbox Code Playgroud)
但是你可以使用win32api(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']
Run Code Online (Sandbox Code Playgroud)
很明显,您可以将win32api.GetShortPathName调用折叠到您的dir探索中,而不是像我的示例中那样嵌套.我已经完成了这样的3次调用,因为如果你已经有一个"太长"的路径,那么win32api.GetShortPathName也不会应付它,但你可以每个dir并且保持低于限制.
要在UNC路径上查找文件,魔术前缀\\?\UNC\
不仅仅是\\?\
.
参考:https://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
所以要访问//server/share/really/deep/path/etc/etc
,你需要
unicode()
构造函数)"\\?\\UNC\"
)和"\"
(请参阅os.path.normpath()
)产生的unicode字符串: \\?\UNC\server\share\really\deep\path\etc\etc
我只尝试了一点(比@stenci少得多)但是使用Python 2.7它似乎可以正常工作os.walk()
,并且失败了os.listdir()
.
警告:它只适用于os.walk(),如果遍历的起始路径在MAX_PATH限制范围内,并且起始路径中的所有子目录都不会超过限制.这是因为os.walk()在顶层目录中使用os.listdir().
归档时间: |
|
查看次数: |
6635 次 |
最近记录: |