gpt4 book ai didi

python - 无法使用 Python 在 Windows 上找到具有长名称的文件

转载 作者:IT老高 更新时间:2023-10-28 22:05:46 26 4
gpt4 key购买 nike

我需要在 Windows 中浏览具有长文件名的文件夹。

我尝试使用 os.listdir(),但它会因路径名太长而崩溃,这很糟糕。

我尝试使用 os.walk(),但它忽略了超过 ~256 的路径名,这更糟。

我尝试了 here 中描述的魔术字解决方法, 但它只适用于映射驱动器,不适用于 UNC pathnames .

这是一个短路径名的示例,它表明 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\\*.*'

知道如何处理长路径名或 unicode UNC 路径名吗?

编辑:

根据下面评论的建议,我创建了一些测试函数来比较 Python 2.7 和 3.3,并添加了 glob.globos.listdir 的测试在 os.chdir 之后。

os.chdir 没有起到预期的作用(参见 comment)。

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

结果如下:

  • 数字 8 表示已找到所有文件
  • 数字 0 表示它甚至没有尝试而不会崩溃
  • 1 到 7 之间的任何数字表示它中途失败而没有崩溃
  • 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

最佳答案

使用 8.3 回退以避免长路径名,在 Win7 资源管理器中浏览这似乎是 windows 本身所做的,即每个长路径都有一个较短的“真实名称”:

>>> long_unc="\\\\K53\\Users\\Tolan\\testing\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\\xxxxxxxxxxxxxxxxxxxxxxxxdddddddddddddddddddddwgggggggggggggggggggggggggggggggggggxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\\esssssssssssssssssssssggggggggggggggggggggggggggggggggggggggggggggggeee"
>>> os.listdir(long_unc)
FileNotFoundError: [WinError 3]

但您可以使用 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']

显然,您可以将 win32api.GetShortPathName 调用折叠到您的目录探索中,而不是像我的示例中那样嵌套。我已经通过 3 次调用完成了这样的操作,因为如果您的路径“太长”,那么 win32api.GetShortPathName 也无法应对,但您可以按目录执行并保持在限制以下。

关于python - 无法使用 Python 在 Windows 上找到具有长名称的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18390341/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com