Python 实战:写一个文件夹体检工具,快速找出大文件

发布时间:2026/10/14 19:32:01

Python 实战:写一个文件夹体检工具,快速找出大文件 下载目录越来越大项目里还混着缓存、安装包和旧日志。想整理之前先回答三个问题有多少文件、哪类文件占得多、最大的文件在哪里这篇文章用 Python 标准库写一个只读的“文件夹体检工具”。复制脚本后就能运行不需要安装第三方依赖也不会主动删除、移动或改写被扫描目录里的文件。图 1Python 官方标志来源Python Software Foundation 官方素材页。Python 标志为 PSF 商标此处用于 Python 技术介绍。文章目录一、先定义“统计什么”二、处理流程扫描、汇总、保留 TOP N三、完整代码保存为 folder_check.py四、怎么运行五、用一组小文件核对结果六、几个值得理解的实现细节1. 为什么用 lstat()而不是直接 stat()2. 为什么必须原地修改 dirs3. 为什么榜单使用最小堆4. 扩展名只是分类线索5. 出错后应该怎么理解结果七、下一步可以怎么扩展参考资料与配图来源一、先定义“统计什么”工具输出普通文件数量、按扩展名汇总的大小以及大文件 TOP N。开始写代码之前先把统计口径说清楚项目本文的处理方式文件大小使用st_size统计逻辑字节数子目录递归扫描可按目录名排除扩展名转为小写.JPG和.jpg合并无扩展名文件归入[无扩展名]符号链接不跟随子目录中的符号链接不计入链接文件权限不足或文件消失记录错误继续扫描其他路径大小单位使用 1024 进制KiB、MiB、GiB这里最容易踩坑的是第一项。稀疏文件的逻辑大小可能明显大于实际占用硬链接的多个路径会被分别计数。因此这份报告适合定位大文件不等于磁盘空间核算也不代表删除后必然释放同样大小的空间。二、处理流程扫描、汇总、保留 TOP N否是否是读取目录与命令行参数遍历目录并排除指定子目录读取文件元数据读取成功且为普通文件?记录错误或跳过更新文件数量与扩展名统计更新容量为 N 的最小堆遍历结束?输出统计与大文件列表图 2本文脚本的处理流程。遇到读取错误会继续扫描遍历结束后通过错误数量和退出码提示结果可能不完整。职责分给三个标准库组件os.walk()遍历目录pathlib.Path处理路径heapq维护大文件榜单。如果只需要最大的 10 个文件就没有必要为了排行榜保存所有文件记录。最小堆里最多放 10 条堆顶是当前榜单中最小的一条遇到更大的文件时再替换它。三、完整代码保存为 folder_check.py下面的脚本面向Python 3.10 及以上版本只依赖标准库。Report regular-file sizes without modifying the scanned directory.importargparseimportheapqimportosimportstatimportsysfromcollectionsimportdefaultdictfrompathlibimportPathdefhuman_size(size):valuefloat(size)forunitin(B,KiB,MiB,GiB,TiB):ifvalue1024orunitTiB:returnf{value:.2f}{unit}value/1024defscan(root,top_n10,excluded()):iftop_n1:raiseValueError(top_n must be positive)excludedset(excluded)groupsdefaultdict(lambda:[0,0])largest[]file_counttotal_byteserror_count0error_samples[]defrecord_error(exc):nonlocalerror_count error_count1iflen(error_samples)5:error_samples.append(str(exc))forbase,dirs,filesinos.walk(root,topdownTrue,onerrorrecord_error,followlinksFalse):dirs[:][namefornameindirsifnamenotinexcluded]fornameinfiles:pathPath(base)/nametry:infopath.lstat()exceptOSErrorasexc:record_error(exc)continueifnotstat.S_ISREG(info.st_mode):continuesizeinfo.st_size extpath.suffix.lower()or[无扩展名]file_count1total_bytessize groups[ext][0]1groups[ext][1]size item(size,str(path.relative_to(root)))iflen(largest)top_n:heapq.heappush(largest,item)elifitemlargest[0]:heapq.heapreplace(largest,item)returnfile_count,total_bytes,groups,largest,error_count,error_samplesdefmain():parserargparse.ArgumentParser(description只读文件夹体检工具)parser.add_argument(directory,typePath,help要扫描的目录)parser.add_argument(--top,typeint,default10,help大文件数量默认 10)parser.add_argument(--exclude,actionappend,default[],help跳过指定名称的子目录可重复传入)argsparser.parse_args()ifargs.top1:parser.error(--top 必须大于 0)try:rootargs.directory.expanduser().resolve(strictTrue)except(OSError,RuntimeError)asexc:parser.error(str(exc))ifnotroot.is_dir():parser.error(目标必须是目录)count,total,groups,largest,errors,samplesscan(root,args.top,args.exclude)print(f目录{root})print(f普通文件{count}个逻辑大小合计{human_size(total)})print(f扫描错误{errors}次)print(\n按扩展名统计逻辑大小降序)forext,(number,size)insorted(groups.items(),keylambdarow:(-row[1][1],row[0])):print(f{ext:12}{number:6}个{human_size(size):12})print(f\n大文件 TOP{args.top})forsize,nameinsorted(largest,reverseTrue):print(f{human_size(size):12}{name!r})forsampleinsamples:print(f警告{sample},filesys.stderr)return1iferrorselse0if__name____main__:raiseSystemExit(main())四、怎么运行扫描下载目录默认显示最大的 10 个文件python folder_check.py~/Downloads扫描项目目录显示 TOP 20同时跳过常见的依赖与版本控制目录python folder_check.py./my-project--top20--exclude.git--excludenode_modules--exclude.venvWindows 可以这样传入路径py folder_check.pyD:\Downloads--top 10在将 Python 命令命名为python3的环境中将示例中的python换成python3即可。含空格的路径需要保留引号。--exclude匹配的是子目录名称区分大小写并在每一层生效。例如--exclude cache会跳过扫描过程中遇到的所有名为cache的子目录。它不是通配符也不会排除同名的普通文件默认不排除任何目录。五、用一组小文件核对结果不要一上来就扫描整个磁盘。先在单独的练习目录中创建一组已知大小的文件确认输出符合预期。下面的准备代码会新建demo目录如果目录已存在会直接报错避免覆盖已有练习数据frompathlibimportPath rootPath(demo)root.mkdir(exist_okFalse)(root/data).mkdir()(root/cache).mkdir()files{notes.txt:1024,photo.JPG:2048,data/data.csv:4096,README:0,cache/tmp.bin:8192,}forname,sizeinfiles.items():(root/name).write_bytes(b0*size)这里的.JPG、.csv只是测试文件名内容均为占位字节不是真实图片或数据表。准备代码会创建文件前面的扫描脚本只读取目录和元数据。然后运行python folder_check.py ./demo--top3--excludecache输出如下首行的绝对路径会随机器变化目录/path/to/demo 普通文件4 个逻辑大小合计7.00 KiB 扫描错误0 次 按扩展名统计逻辑大小降序 .csv 1 个 4.00 KiB .jpg 1 个 2.00 KiB .txt 1 个 1.00 KiB [无扩展名] 1 个 0.00 B 大文件 TOP 3 4.00 KiB data/data.csv 2.00 KiB photo.JPG 1.00 KiB notes.txt可以手算验证1024 2048 4096 0 7168字节即7 KiB。cache/tmp.bin被排除README虽然为空仍然是一个普通文件。本文配套脚本已在独立临时目录中检查了总大小、TOP N 顺序、大小写扩展名合并、空文件、空目录、目录排除、文件与目录符号链接、失效链接、非法参数及遍历错误。这里没有做跨操作系统实测或大规模性能基准。六、几个值得理解的实现细节1. 为什么用 lstat()而不是直接 stat()stat()默认跟随符号链接可能把链接指向的文件再算一遍。lstat()获取链接本身的元数据配合stat.S_ISREG()只把普通文件加入统计。遍历时的followlinksFalse用来避免进入子目录符号链接如果用户传入的起始目录本身是符号链接resolve()会先解析到目标目录。Windows 的目录联接、其他重解析点以及挂载点不应直接等同于普通符号链接本例没有提供跨文件系统隔离或完整的重解析点策略。2. 为什么必须原地修改 dirsdirs[:][namefornameindirsifnamenotinexcluded]在topdownTrue时os.walk()会依据dirs列表继续向下遍历。使用切片赋值能修改它实际使用的列表如果仅写成dirs [...]只是重新绑定局部变量不能阻止遍历进入这些子目录。3. 为什么榜单使用最小堆设普通文件数为 F、榜单容量为 K。维护榜单的时间复杂度约为O(F log K)榜单自身额外空间为O(K)输出前再对这 K 条记录排序。这并不意味着整个扫描过程只用O(K)内存。扩展名汇总需要存储每一种扩展名os.walk()也会维护目录遍历所需的数据。更准确的说法是脚本不为 TOP N 榜单保存全量文件记录。4. 扩展名只是分类线索Path.suffix取最后一段扩展名所以backup.tar.gz会归入.gz.gitignore这类文件通常没有这里所说的扩展名。若要识别组合后缀可根据业务规则使用suffixes。扩展名也不代表真实格式。改名后的图片仍可能是图片脚本没有读取文件内容来判断类型。5. 出错后应该怎么理解结果脚本最多打印 5 条错误详情同时保留错误总数。退出码0表示本次扫描没有捕获到读取错误1表示存在扫描错误、结果可能不完整命令行参数错误通常返回2。文件系统可能在扫描期间变化所以输出是扫描过程中逐个观察到的结果不是某一时刻的原子快照。对正在高速写入的日志目录前后两次统计不同属于正常现象。七、下一步可以怎么扩展这个工具已经可以用于整理下载目录、排查项目缓存和定位大日志。继续练习时可以给它增加 CSV 导出、按修改时间筛选或为每个一级子目录生成汇总。如果要加入清理功能建议先生成候选清单与预览再设计确认和恢复机制。统计报告已经能帮助定位问题没有必要在第一次运行时就自动删除文件。参考资料与配图来源Python 官方文档os.walkPython 官方文档pathlibPython 官方文档heapqPython Software Foundation官方标志素材及使用说明创作说明本文由 AI 辅助撰写示例脚本已运行验证流程图为本文配套绘制Python 标志来源见图下注释。
延伸阅读

更多相关文章

2026/10/14 19:32:01

MES车间管理源码完整版:可运行可调试的制造执行系统基线

简介:本资源是一套面向制造业数字化转型场景的MES车间管理信息系统完整源码,适用于工业软件开发工程师、智能制造系统集成人员及高校相关专业高年级学生,用于学习车间级生产执行系统的架构设计、数据流处理与设备协同控制逻辑。压缩包为ZIP格…

2026/10/14 19:32:01

本地商家折扣卡平台,用户增长运营策略

本地商家折扣卡平台,用户增长运营策略本地商家折扣卡平台的增长核心是打通门店引流、社交裂变、复购唤醒、渠道归因的闭环,区别于普通电商,所有增长动作最终都要落地到线下门店核销。很多平台在运营时,容易出现渠道来源无法追踪、…

2026/10/14 19:32:01

别再把企业知识库做成网盘:权限、RAG、公众号初稿怎么一起落地

文档越来越多,真正的问题却不是“存在哪里”,而是:谁能看、能不能快速找到、AI 回答有没有依据、内部知识能否继续转化为内容。本项目是一套可私有化部署的多部门权限企业知识库。它用 Spring Boot React 管理文档与权限,用关键词…

2026/10/14 21:12:53

汽车零部件采购降本新思路:8Manage SRM竞价管理实战解析

汽车零部件行业的采购降本,这几年已经从“压价”变成了“体系战”。整车厂年年要求年降,原材料波动又是常态,零部件供应商夹在中间,采购部门如果不靠系统工具,单凭人工谈判和经验判断,基本很难在保证质量交…

2026/10/14 21:12:53

Ponytail:零配置Web运行时调试探针实战指南

1. “Ponytail”不是发型,是开发者圈里悄然走红的轻量级调试探针最近在几个前端技术群和内部分享会上,我连续三次听到有人问:“你用过 Ponytail 吗?”——不是在聊扎马尾辫的技巧,也不是美妆博主的新栏目,而…

2026/10/14 21:12:53

最小瓶颈路与Kruskal重构树:从Road题到图论进阶

前两天刷题的时候碰见一道题号 #596、题名叫road的图论题,读完题面第一反应就是经典的“最小瓶颈路”。题目本身不长,但想把它讲透彻,背后牵扯出的是最小生成树、树上倍增、Kruskal 重构树一整套东西。这篇文章就把当时从读题到 AC 的完整思考…

2026/10/14 21:12:53

支付应用首页Flexbox布局实战:从拆解到代码零基础也能掌握

做前端这些年,我见过不少人把Flex布局的文档翻来覆去看了好几遍,真到写页面的时候还是不知道用哪个属性。后来我发现一个特别好用的练手项目:拿一个支付类应用首页当靶子,纯粹用Flexbox把它还原一遍。这个练习在不少前端学习资料里…

2026/10/14 21:07:52

实现 Android 字符设备驱动

这个模块共有四篇: 1.实现 Android 字符设备驱动 2.Android 15 及以上版本创建系统级 app 并测试驱动 3.在 Android 系统中自定义 LedManagerService 服务并提供给 app 使用 4.为 LedManagerService 添加区权限申请功能 一、开发环境 LineageOS 23.2 (…

2026/10/14 11:31:03

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/14 17:41:07

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/14 2:32:55

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/14 0:00:33

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:33

macOS/iOS高精度计时:mach_absolute_time原理与实战

1. 项目概述:为什么mach_absolute_time是 macOS/iOS 时间测量的“黄金标准”在 macOS 和 iOS 开发中,我见过太多人用CFAbsoluteTimeGetCurrent()或NSDate.timeIntervalSinceReferenceDate做性能打点,结果在高精度场景下被系统时钟跳变、NTP 同…

2026/10/14 0:00:33

SCORM课件演示与测试全解析:从API通信到自动化验证

简介:这是一套遵循SCORM标准的交互式课件演示与测试资源,面向E-Learning课程开发者、LMS平台测试人员及在线教学从业者,用于验证课件在不同学习管理系统中的识别、传递与跟踪能力。压缩包共28个文件,约12.07MB,以swf动…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑