Python获取指定目录下文件数量及总大小

本文介绍了一个用于递归遍历指定目录及其子目录,并统计所有文件大小及数量的Python脚本。该脚本还能够显示文件夹的数量,并将文件大小转换为更易读的格式。

欢迎大家访问我的网站:omegaxyz.com

import os

totalSize = 0
fileNum = 0
dirNum = 0


def visitDir(path):
    global totalSize
    global fileNum
    global dirNum
    for lists in os.listdir(path):
        sub_path = os.path.join(path, lists)
        print(sub_path)
        if os.path.isfile(sub_path):
            fileNum = fileNum+1                      # 统计文件数量
            totalSize = totalSize+os.path.getsize(sub_path)  # 文件总大小
        elif os.path.isdir(sub_path):
            dirNum = dirNum+1                       # 统计文件夹数量
            visitDir(sub_path)                           # 递归遍历子文件夹


def sizeConvert(size):                                   # 单位换算
    K, M, G = 1024, 1024**2, 1024**3
    if size >= G:
        return str(size/G)+'G Bytes'
    elif size >= M:
        return str(size/M)+'M Bytes'
    elif size >= K:
        return str(size/K)+'K Bytes'
    else:
        return str(size)+'Bytes'


def main(path):
    if not os.path.isdir(path):
        print('Error:"', path, '" is not a directory or does not exist.')
        return
    visitDir(path)

def output(path):
    print('The total size of '+path+' is:'+sizeConvert(totalSize))
    print('The total number of files in '+path+' is:',fileNum)
    print('The total number of directories in '+path+' is:',dirNum)


if __name__ == '__main__':
    path = r'E://Files'
    main(path)
    output(path)
<think>好的,我现在需要帮助用户解决如何使用Python遍历指定目录下的所有二级目录下的文件。首先,我得理解用户的具体需求。用户提到“二级目录下的文件”,可能是指主目录下的子目录中的文件,也就是主目录是一级,其子目录是二级,而用户需要获取这些二级子目录中的文件。不过也有可能用户指的是主目录下的所有子目录及其子目录下的文件,即包括二级及更深层次的文件?但根据用户之前的提问,他们可能是指主目录下的直接子目录中的文件,也就是只遍历到二级目录,不进入更深层次。 接下来,我需要考虑用户可能的场景。用户可能需要在处理大量文件时,比如整理文档、批量处理数据或者进行文件分析,需要自动化地获取这些文件的路径。他们可能对Python文件操作不太熟悉,所以需要详细的步骤说明和代码示例。 然后,我需要回忆Python中用于遍历目录的模块,主要是os和os.path,以及可能用到的glob模块。os.walk是常用的方法,可以遍历目录树,但需要正确使用它来限制遍历的深度。另外,用户可能希望避免使用过于复杂的库,保持代码简洁易懂。 接下来,我需要验证我的思路是否正确。比如,假设主目录是root_dir,那么一级子目录是root_dir下的各个子目录,二级目录就是这些一级子目录下的子目录。但用户的问题描述是“所有二级目录下的文件”,可能是指主目录下的二级子目录(即主目录的子目录的子目录)中的文件?或者是指主目录下的所有子目录(二级目录)中的文件?这里可能存在歧义,需要进一步确认。 但根据用户的问题描述,“指定目录下的所有二级目录下的文件”,可能是指主目录下的所有二级子目录中的文件。例如,指定目录为A,那么结构可能是A/B/C/file.txt,其中B是一级子目录,C是二级子目录,用户需要获取C中的文件。或者用户可能将主目录视为一级,其子目录视为二级,因此需要获取这些子目录中的文件。需要明确这一点。 假设用户是指主目录下的所有直接子目录(即二级目录)中的文件,那么遍历这些子目录中的文件即可。例如,主目录是A,子目录是A/B、A/C,那么遍历B和C目录下的所有文件,不管这些文件在B或C的哪一级子目录中。或者用户可能希望只获取二级目录下的直接文件,不包含更深层次的子目录中的文件。 这可能需要进一步澄清,但根据常见需求,可能用户希望获取指定目录下所有子目录中的文件,包括子目录的子目录中的文件。即遍历所有二级及更深层次的目录中的文件。但用户明确提到“所有二级目录下的文件”,可能需要限制遍历深度为二级。 这里可能存在不同的理解,因此我需要给出两种可能的解决方案:一种是遍历所有子目录中的文件(不限深度),另一种是仅遍历指定目录下的二级子目录中的文件(即深度为2)。然后可能需要解释这两种情况,让用户根据自己的需求选择。 现在,我需要组织回答的结构。首先,说明使用Python的os模块和os.walk方法,或者glob模块,然后给出代码示例,并解释代码的逻辑。同时,需要处理可能的异常情况,比如权限问题,或者符号链接等,但用户可能不需要太复杂的处理,保持代码简单。 另外,考虑到用户可能需要将文件路径存储起来进行后续处理,代码示例应该展示如何收集所有文件的路径。同时,可能需要解释如何限制遍历的深度,比如只遍历到二级目录结步骤: 1. 导入必要的模块,如os。 2. 使用os.walk遍历目录。 3. 确定遍历的深度,如果是二级目录,可能需要判断当前目录的深度。 4. 收集所有符合条件的文件路径。 5. 处理可能的异常或排除某些目录。 6. 提供示例代码和解释。 或者使用glob模块的递归匹配,但glob在某些情况下可能不够灵活,因此os.walk可能更合适。 在编写代码时,需要注意不同操作系统下的路径分隔符问题,使用os.path.join来处理路径拼接。 可能的代码示例: 使用os.walk遍历所有子目录中的文件: import os def list_files(root_dir): file_list = [] for root, dirs, files in os.walk(root_dir): for file in files: file_path = os.path.join(root, file) file_list.append(file_path) return file_list 但如果要限制到二级目录,即主目录下的子目录中的文件,而不包括更深层次的文件,那么需要计算遍历的深度。例如,root_dir的深度为0,其子目录为深度1,子目录的子目录为深度2。但如何计算深度?可以通过将root分割成组成部分的数量来判断。 例如: root_dir = '/path/to/dir' depth = root_dir.count(os.sep) for root, dirs, files in os.walk(root_dir): current_depth = root.count(os.sep) - depth if current_depth <= 1: # 限制到二级目录(深度为1) for file in files: file_path = os.path.join(root, file) file_list.append(file_path) else: del dirs[:] # 不继续遍历更深目录 这里,假设root_dir的深度为初始值,计算当前目录相对于root_dir的深度。如果限制到二级目录,即只处理深度为0(root_dir本身)、1(一级子目录)、或者深度为1(仅一级子目录)?需要根据用户需求调整。例如,如果用户只需要二级目录下的文件,即主目录的子目录中的文件,那么current_depth应等于1。此时,root_dir的深度为n,root的深度为n+1,所以current_depth = (root的深度) - (root_dir的深度) =1。然后,在处理时,只收集该深度下的文件。 例如: root_dir = 'parent_dir' parent_depth = root_dir.count(os.sep) for root, dirs, files in os.walk(root_dir): current_depth = root.count(os.sep) - parent_depth if current_depth == 1: # 该目录是一级子目录,即二级目录 for file in files: file_list.append(os.path.join(root, file)) elif current_depth > 1: # 超过二级,跳过 del dirs[:] 这样,只会遍历到一级子目录(即二级目录)中的文件,不进入更深层次。 但用户的问题可能是指定目录下的所有二级目录,即主目录下的子目录的子目录中的文件。例如,主目录是A,那么A/B/C/file.txt中的C是二级目录,需要收集C中的文件。这时候,需要限制深度为2。此时,current_depth等于2。 或者,用户可能将主目录视为一级目录,其子目录为二级目录,需要遍历这些二级目录中的文件。这时候,主目录下的子目录就是二级目录,因此深度为1。 这里可能存在歧义,需要明确。根据常见的文件系统结构,通常根目录是层级0,其子目录是层级1,子目录的子目录是层级2。所以,如果用户想遍历指定目录下的所有二级子目录中的文件,即层级2的目录,那么需要设置current_depth == 2。例如,指定目录是A,结构如下: A (层级0) ├─ B1 (层级1) │ ├─ C1 (层级2) │ │ └─ file1.txt │ └─ C2 (层级2) │ └─ file2.txt └─ B2 (层级1) └─ C3 (层级2) └─ file3.txt 用户可能想获取C1、C2、C3中的文件,即层级2的目录中的文件。此时,代码需要遍历到层级2的目录,并收集其中的文件。 或者,用户可能想获取所有位于二级目录下的文件,不管层级如何,比如主目录下的所有子目录(无论层级)中的文件。这需要明确。 根据用户的问题描述,“所有二级目录下的文件”,可能是指主目录下的所有子目录(即一级子目录)中的文件,也就是层级1的目录中的文件。这时候,只需要遍历这些一级子目录中的文件,而不管这些子目录是否有更深层次的目录。例如,主目录是A,其子目录是B1、B2,用户需要获取B1和B2中的所有文件,包括它们的子目录中的文件。或者用户可能只需要直接位于B1和B2中的文件,不包括它们的子目录中的文件。 这又分两种情况:遍历一级子目录下的所有文件(包括子目录中的文件),或者仅遍历一级子目录下的直接文件(不包含子目录中的文件)。用户的问题描述中的“二级目录下的文件”可能指的是前者,即一级子目录下的所有文件,无论层级。例如,主目录是A,一级子目录是B1、B2,那么B1下的所有文件(包括B1/C1中的文件)都属于二级目录下的文件? 这里可能需要进一步澄清,但根据常见理解,可能用户希望遍历指定目录下的所有直接子目录(一级子目录)中的所有文件,包括这些子目录的子目录中的文件。即,获取所有位于一级子目录及其子目录中的文件。这时候,使用os.walk遍历每个一级子目录,并收集所有文件。 或者,用户可能希望遍历到二级目录,即主目录的子目录的子目录,而忽略更深层次。例如,只获取A/B1/C1中的文件,而不会进入A/B1/C1/D1中的文件。 综上所述,可能需要提供两种方案:一种是遍历所有子目录中的文件(不限深度),另一种是限制深度到二级目录。根据用户的问题,可能后者更符合需求,但需要明确。 在回答中,应该先给出通用的遍历所有子目录中的文件的方法,然后解释如何限制深度到二级目录,以满足不同需求。 另外,用户可能需要排除某些目录,或者处理特定的文件类型,但问题中没有提到,所以可能不需要涉及。 最后,代码示例应该简洁,并附有解释,说明每一部分的作用,以及如何根据需求调整深度限制。</think>--- ### 一、需求理解与方案选择 需要遍历**指定目录下的所有二级子目录中的文件**,这里可能存在两种理解: 1. **主目录的直接子目录下的所有文件**(即 `主目录/子目录A/文件` 或 `主目录/子目录A/更深子目录/文件`) 2. **主目录的二级子目录下的文件**(即 `主目录/子目录A/二级子目录/文件`,不包含三级及更深目录) 以下提供两种场景的Python实现方法。 --- ### 二、实现代码与详细解释 #### 场景1:遍历所有直接子目录下的文件(不限深度) ```python import os def get_all_subdir_files(root_dir): """获取指定目录下所有子目录中的文件(包括子目录的子目录)""" file_paths = [] # 遍历主目录下的所有子目录 for entry in os.scandir(root_dir): if entry.is_dir(): # 遍历每个子目录及其所有下级目录 for root, _, files in os.walk(entry.path): for file in files: file_paths.append(os.path.join(root, file)) return file_paths # 示例调用 files = get_all_subdir_files("/path/to/your/directory") print(f"找到 {len(files)} 个文件") ``` #### 场景2:仅遍历二级子目录下的文件(精确控制深度) ```python import os def get_second_level_files(root_dir): """精确获取二级子目录中的文件(不包含更深层级)""" file_paths = [] # 第一层遍历:主目录的直接子目录 for l1_dir in os.scandir(root_dir): if l1_dir.is_dir(): # 第二层遍历:直接子目录下的内容 for entry in os.scandir(l1_dir.path): if entry.is_file(): file_paths.append(entry.path) elif entry.is_dir(): # 如果还需要三级目录中的文件,可在此继续循环 pass return file_paths # 示例调用 files = get_second_level_files("/path/to/your/directory") print(f"找到 {len(files)} 个文件") ``` --- ### 三、进阶技巧与功能扩展 #### 1. 过滤特定类型文件 ```python # 只收集图片文件 allowed_ext = ['.jpg', '.png', '.gif'] file_paths = [ os.path.join(root, file) for root, _, files in os.walk(root_dir) for file in files if os.path.splitext(file)[1].lower() in allowed_ext ] ``` #### 2. 排除隐藏文件/目录 ```python for root, dirs, files in os.walk(root_dir): # 过滤隐藏目录(以`.`开头的目录,如.git) dirs[:] = [d for d in dirs if not d.startswith('.')] # 过滤隐藏文件 visible_files = [f for f in files if not f.startswith('.')] ``` #### 3. 性能优化版(使用生成器) ```python def fast_file_scanner(root_dir): """生成器形式逐文件返回,节省内存""" for root, _, files in os.walk(root_dir): for file in files: yield os.path.join(root, file) # 使用示例 for file_path in fast_file_scanner("/path/to/dir"): print(file_path) ``` --- ### 四、方案对比表 | 方法 | 特点 | 适用场景 | |-----------------------|----------------------------------------------------------------------|-----------------------------------| | `os.scandir()` + `os.walk()` | 深度优先遍历,可获取完整路径 | 需要遍历子目录的子目录 | | 纯`os.walk()` | 简洁但可能包含主目录本身的文件 | 允许包含主目录下的直接文件 | | 生成器模式 | 内存友好,适合大规模文件遍历 | 处理数十万级文件 | | 深度控制版 | 精确控制遍历层级 | 明确知道目录结构的场景 | --- ### 五、常见问题解决 1. **路径权限问题** ```python try: for entry in os.scandir(path): # 正常处理 except PermissionError: print(f"无权限访问: {path}") ``` 2. **处理符号链接** ```python os.walk(..., followlinks=True) # 默认False不跟随符号链接 ``` 3. **跨平台路径格式** ```python from pathlib import Path file_path = Path(root) / file # 自动处理Windows/MacOS/Linux路径差异 ``` --- ### 六、推荐工具组合 - **可视化检查**:使用 `tree` 命令生成目录树(需先安装): ```bash # Linux/Mac tree -L 2 /path/to/dir # 显示二级目录结构 # Windows(需安装TreeCmd) tree /F /A /L:2 C:\your\dir ``` - **交互式探索**:在Jupyter中实时查看: ```python from IPython.display import display display(pd.DataFrame({"文件路径": file_paths})) ``` --- 根据实际需求选择具体方案,若需要更复杂的过滤逻辑(如按文件名模式、文件大小等),可结合 `glob` 模块或 `pathlib` 库实现更精细的控制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值