使用Python在Linux和Windows中查找文件的最快方法是什么?

时间:2013-11-07 05:46:28

标签: python linux windows

我正在用Python编写RawTherapee的插件。我需要从名为“AboutThisBuild.txt”的文件中提取版本号,该文件可能存在于目录树中的任何位置。虽然RawTherapee知道它的安装位置,但这些数据会被烘焙到二进制文件中。

我的插件设计用于在没有任何命令行参数的情况下运行时收集基本系统数据,以便进行短路故障排除。通过拥有版本号,修订号和变更集(AKA Mercurial),我可以理清脚本可能无法按预期工作的原因。好的是上下文。

我尝试过各种方法,有些方法在本网站的其他地方提出。主要是使用os.walk和fnmatch。

问题在于速度。搜索整个目录树就像看油漆一样干!

为了减少负载,我试图预测可能的隐藏位置,并且只能遍历这些。这样更快,但缺少一些文件的明显缺点。

这就是我现在所拥有的。在Linux上测试但尚未测试Windows,因为我仍在研究可能放置文件的位置。

import fnmatch
import os
import sys

rootPath = ('/usr/share/doc/rawtherapee',
            '~',
            '/media/CoreData/opt/',
            '/opt')
pattern = 'AboutThisBuild.txt'

# Return the first instance of RT found in the paths searched
for CheckPath in rootPath:
    print("\n")
    print(">>>>>>>>>>>>> " + CheckPath)
    print("\n")
    for root, dirs, files in os.walk(CheckPath, True, None, False):
        for filename in fnmatch.filter(files, pattern):
            print( os.path.join(root, filename))
            break

通常,“AboutThisBuild.txt”存储在名为“rawtherapee”的目录/子目录中,或者在目录树中的某处包含字符串。虽然我可以获得5000个奇怪的目录名称并搜索这些'rawtherapee'然后使用os.walk来遍历这些目录,但我查看了所有模块和函数来整理目录中的所有文件(再次)。 >

任何人都有更快捷的搜索整个目录树的方法,还是我坚持使用这种混合选项?

3 个答案:

答案 0 :(得分:1)

我是Python的初学者,但我想我知道在Windows中查找文件的最简单方法。

import os
for dirpath, subdirs, filenames in os.walk('The directory you wanna search the file in'):
    if 'name of your file with extension' in filenames:
        print(dirpath)

此代码将打印出您要在控制台中搜索的文件的目录。您所要做的就是进入目录。

答案 1 :(得分:0)

关于搜索的事情是,你到达那里并不重要(例如作弊)。获得结果后,您可以相对快速地验证它是否正确。

您可以通过猜测相当有效地识别候选位置。例如,在Linux上,您可以首先尝试查看这些位置(显然不是所有目录,但它不会对os.path.isfile('/;l$/AboutThisBuild.txt')造成任何伤害)

$ strings /usr/bin/rawtherapee | grep '^/'
/lib/ld-linux.so.2
/H=!
/;l$
/9T$,
/.ba
/usr/share/rawtherapee
/usr/share/doc/rawtherapee
/themes/
/themes/slim
/options
/usr/share/color/icc
/cache
/languages/default
/languages/
/languages
/themes
/batch/queue
/batch/
/dcpprofiles
/@q=
/N6rtexif16NAISOInterpreterE

如果安装了它,可以尝试locate命令

如果您仍然找不到它,请转到强力方法

这是使用Python

strings的粗略等价物
>>> from string import printable, whitespace
>>> from itertools import groupby
>>> pathchars = set(printable) - set(whitespace)
>>> with open("/usr/bin/rawtherapee") as fp:
...     data = fp.read()
... 
>>> for k, g in groupby(data, pathchars.__contains__):
...     if not k: continue
...     g = ''.join(g)
...     if len(g) > 3 and g.startswith("/"):
...         print g
... 
/lib64/ld-linux-x86-64.so.2
/^W0Kq[
/pW$<
/3R8
/)wyX
/WUO
/w=H
/t_1
/.badpixH
/d$(
/\$P
/D$Pv
/D$@
/D$(
/l$@
/d$@v?H
/usr/share/rawtherapee
/usr/share/doc/rawtherapee
/themes/
/themes/slim
/options
/usr/share/color/icc
/cache
/languages/default
/languages/
/languages
/themes
/batch/queue.csv
/batch/
/dcpprofiles
/@q=
/N6rtexif16NAISOInterpreterE

答案 2 :(得分:0)

听起来你需要一个纯粹的python解决方案。如果没有,其他答案就足够了。

在这种情况下,您应该使用队列和线程遍历文件夹。虽然有些人可能会说Threads永远不是解决方案,但是当你受I / O约束时,Threads是一种加速的好方法,在这种情况下你就是这样。基本上,你将os.listdir当前目录。如果它包含你的文件,那么派对就像1999年一样。如果没有,请将每个子文件夹添加到工作队列中。

如果你很聪明,你可以使用depth first vs breadth first遍历来获得最佳效果。

我在http://www.tutorialspoint.com/python/python_multithreading.htm的工作中非常成功地使用了一个很好的例子。请参阅标题为Multithreaded Priority Queue的部分。可能会更新示例以包含线程池,但这不是必需的。