繁体   English   中英

Python计算目录及其所有子目录中的文件

[英]Python count files in a directory and all its subdirectories

我正在尝试计算文件夹及其所有子文件夹中的所有文件例如,如果我的文件夹如下所示:

file1.txt
subfolder1/
├── file2.txt
├── subfolder2/
│   ├── file3.txt
│   ├── file4.txt
│   └── subfolder3/
│       └── file5.txt
└── file6.txt
file7.txt

我想要7号。

我尝试的第一件事是一个递归函数,它计算所有文件并为每个文件夹调用自身

def get_file_count(directory: str) -> int:

    count = 0

    for filename in os.listdir(directory):

        file = (os.path.join(directory, filename))

        if os.path.isfile(file):
            count += 1

        elif os.path.isdir(file):
            count += get_file_count(file)

    return count

这种方式有效,但需要大量时间来处理大目录。

我还记得这篇文章,它显示了一种使用 win32com 计算文件夹总大小的快速方法,我想知道这个库是否也提供了一种方法来做我正在寻找的事情。 但是经过搜索,我只找到了这个

fso = com.Dispatch("Scripting.FileSystemObject")
folder = fso.GetFolder(".")
size = folder.Files.Count

但这仅返回目标文件夹(而不是其子文件夹)中的文件数

那么,您知道python中是否有一个最佳函数可以返回文件夹及其所有子文件夹中的文件数吗?

IIUC,你可以做到

sum(len(files) for _, _, files in os.walk('path/to/folder'))

或者,为了避免使用len以获得更好的性能:

sum(1 for _, _, files in os.walk('folder_test') for f in files)

此代码将显示来自指定根的所有非目录(例如,纯文件、符号链接)的目录条目的计数。

包括时间和测试中使用的实际路径名:

from glob import glob, escape
import os
import time


def get_file_count(directory: str) -> int:
    count = 0
    for filename in glob(os.path.join(escape(directory), '*')):
        if os.path.isdir(filename):
            count += get_file_count(filename)
        else:
            count += 1
    return count

start = time.perf_counter()
count = get_file_count('/Volumes/G-DRIVE Thunderbolt 3')
end = time.perf_counter()

print(count)
print(f'{end-start:.2f}s')

输出:

166231
2.38s

我用过 os.walk()

这是我的样品,我希望它会帮助你

def file_dir():
    directories = []
    res = {}
    cwd = os.getcwd()
    for root, dirs, files in os.walk(cwd):
        for file in files:
            if file.endswith(".tsv"):
                directories.append(os.path.join(root, file))
    res['dir'] = directories
    return res

也可以直接使用命令:

find DIR_NAME -type f | wc -l

这将返回所有文件的计数使用os.system()这可以从 python 完成。

使用库osPath的另一个解决方案:

from pathlib import Path
from os.path import isfile

len([x for x in Path('./dir1').rglob('*') if isfile(x)])

正确的方法是使用os.walk正如其他人所指出的那样,但要提供另一种尽可能类似于您的原始解决方案的解决方案:

您可以使用os.scandir来避免构建整个列表的成本,它应该会更快:

def get_file_count(directory: str) -> int:
    count = 0

    for entry in os.scandir(directory):
        if entry.is_file():
            count += 1

        elif entry.is_dir():
            count += get_file_count(os.path.join(directory, entry.name))

    return count

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM