我想在目录树中找到具有给定文件扩展名的所有文件。但是,有些文件夹非常大,因此如果花费太长时间(例如1秒),我想停止此过程。我当前的代码看起来像这样:
import os
import time
start_time = time.time()
file_ext = '.txt'
path = 'C:/'
file_list = []
for root, dirs, files in os.walk(path):
for file in files:
if file.endswith(file_ext):
relDir = os.path.relpath(root, path)
relFile = os.path.join(relDir, file)
file_list.append(relFile)
if time.time() - start_time> 1:
break
if time.time() - start_time> 1:
break
这段代码的问题在于,当我到达一个非常大的子文件夹时,在完全遍历该文件夹之前,此代码不会中断。如果该文件夹包含许多文件,则可能需要比我想要的更长的时间。有什么办法可以确保代码的运行时间不超过规定的时间吗?
编辑:请注意,虽然找到加速代码的方法肯定有帮助(例如使用os.scandir),但这个问题主要涉及如何终止正在运行的进程。
答案 0 :(得分:0)
你可以在子进程中执行并杀死它。选项包括multiprocessing.Process
,但Windows上的多处理库可能需要做大量您不需要的工作。相反,你可以将walker代码传递到python子进程中并从那里开始。
import os
import sys
import threading
import subprocess as subp
walker_script = """
import os
import sys
path = os.environ['TESTPATH']
file_ext = os.environ['TESTFILEEXT']
# let parent know we are going
print('started')
for root, dirs, files in os.walk(path):
for file in files:
if file.endswith(file_ext):
relDir = os.path.relpath(root, path)
relFile = os.path.join(relDir, file)
print(relFile)
"""
file_ext = '.txt'
path = 'C:/'
encoding = sys.getdefaultencoding()
# subprocess reads directories... additional python flags seek to
# speed python initialization. If a linuxy system, forking would
# be a good option.
env = {'TESTPATH':path, 'TESTFILEEXT':file_ext}
env.update(os.environ)
proc = subp.Popen([sys.executable, '-E', '-s', '-S', '-'], stdin=subp.PIPE,
stdout=subp.PIPE, # , stderr=open(os.devnull, 'wb'))
env = env)
# write walker script
proc.stdin.write(walker_script.encode('utf-8'))
proc.stdin.close()
# wait for start marker
next(proc.stdout)
# timer kills directory traversal when bored
threading.Timer(1, proc.kill).start()
file_list = [line.decode(encoding).strip() for line in proc.stdout]
print(file_list)