我有一个目录,其中有大约数十万个文本文件。
Python 代码创建此文件的名称列表,
listoffiles = os.listdir(directory)
用64部分的lol
功能打破这个listoffiles
lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)]
partitioned_listoffiles = lol(listoffiles, 64)
然后我把它汇集到 2 个进程
pool = Pool(processes=2,)
single_count_tuples = pool.map(Map, partitioned_listoffiles)
在Map
函数中,我读取这些文件并进行进一步处理
我的问题是,如果我对包含数千个文件的小文件夹执行此操作,则此代码可以正常工作。大目录内存不足。我应该如何解决这个问题。我可以先读取 n 个文件,然后读取下一个 n 个文件并创建listoffiles
并在 for 循环中处理此步骤吗?
如果目录非常非常大,那么您可以使用scandir()
而不是os.listdir()
。但os.listdir()
不太可能导致MemoryError
因此问题出在其他两个地方:
-
使用生成器表达式而不是列表推导:
chunks = (lst[i:i+n] for i in range(0, len(lst), n))
-
使用
pool.imap
或pool.imap_unordered
代替pool.map()
:for result in pool.imap_unordered(Map, chunks): pass
或更好:
files = os.listdir(directory)
for result in pool.imap_unordered(process_file, files, chunksize=100):
pass
我遇到了一个非常类似的问题,我需要验证特定文件夹中是否有一定数量的文件。问题是该文件夹可能包含多达 2000 万个非常小的文件。据我所知,不可能将 python listdir
限制为一定数量的项目。
我的listdir
需要相当长的时间来列出目录和大量 RAM,但设法在具有 4GB RAM 的 VM 上运行。
您可能需要尝试改用 glob
,这可能会使文件列表更小,具体取决于您的要求。
import glob
print glob.glob("/tmp/*.txt")