尝试#2:
人们似乎并不理解我想要做什么。让我看看我是否可以更清楚地说明它:
1)读取文件列表比遍历目录要快得多。
2)所以让我们有一个遍历目录并将结果列表写入文件的函数。现在,将来,如果我们想获取该目录中的所有文件,我们可以只读取该文件而不是遍历目录。我将此文件称为索引。
3) 显然,随着文件系统的变化,索引文件会失去同步。为了克服这个问题,我们有一个单独的程序连接到操作系统中,以监控文件系统的变化。它将这些更改写入一个称为监控日志的文件。在我们读取特定目录的索引文件后,我们立即使用监控日志将各种更改应用于索引,以便它反映目录的当前状态。
因为读取文件比遍历目录要便宜得多,所以这应该比在第一次调用之后遍历所有调用要快得多。
原帖:
我想要一个函数,它将递归地获取任何给定目录中的所有文件并根据各种参数过滤它们。而且我希望它快——比如,比简单地走目录快一个数量级。我更喜欢用 Python 来做。跨平台更可取,但 Windows 最重要。
这是我关于如何解决这个问题的想法:
我有一个名为 all_files 的函数:
def all_files(dir_path, ...parms...):
...
我第一次调用这个函数时,它将使用 os.walk 构建所有文件的列表,以及有关文件的信息,例如它们是否被隐藏、符号链接等。我将把这些数据写入文件在目录中称为“.index”。在随后对 all_files 的调用中,将检测到 .index 文件,我将读取该文件而不是遍历目录。
这会导致在添加和删除文件时索引不同步的问题。为此,我将有第二个程序在启动时运行,检测对整个文件系统的所有更改,并将它们写入一个名为“mod_log.txt”的文件。它通过 Windows 信号检测变化,就像这里描述的方法一样。该文件每行包含一个事件,每个事件由受影响的路径、事件类型(创建、删除等)和时间戳组成。.index 文件也将有一个时间戳,以及它最后一次更新的时间。在我读取 all_files 中的 .index 文件后,我将跟踪 mod_log.txt 并查找在 .index 文件中的时间戳之后发生的任何事件。它将获取这些最近的事件,找到适用于当前目录的任何事件,并相应地更新 .index。
最后,我将所有文件的列表,根据各种参数过滤,并返回结果。
你觉得我的做法怎么样?有一个更好的方法吗?
编辑:
检查此代码。通过递归遍历读取缓存列表,我看到了显着的加速。
import os
from os.path import join, exists
import cProfile, pstats
dir_name = "temp_dir"
index_path = ".index"
def create_test_files():
os.mkdir(dir_name)
index_file = open(index_path, 'w')
for i in range(10):
print "creating dir: ", i
sub_dir = join(dir_name, str(i))
os.mkdir(sub_dir)
for i in range(100):
file_path = join(sub_dir, str(i))
open(file_path, 'w').close()
index_file.write(file_path + "\n")
index_file.close()
#
# 0.238 seconds
def test_walk():
for info in os.walk("temp_dir"):
pass
# 0.001 seconds
def test_read():
open(index_path).readlines()
if not exists("temp_dir"):
create_test_files()
def profile(s):
cProfile.run(s, 'profile_results.txt')
p = pstats.Stats('profile_results.txt')
p.strip_dirs().sort_stats('cumulative').print_stats(10)
profile("test_walk()")
profile("test_read()")