os.path.getsize() 仅支持文件,统计文件夹需用 os.walk() 遍历并捕获 PermissionError/OSError,结果转 MiB(÷1024²)显示,推荐 pathlib.Path 处理长路径。

os.path.getsize() 不能直接统计文件夹大小
调用 os.path.getsize() 传入目录路径会抛出 OSError: [Errno 21] Is a directory —— 它只认文件,不认文件夹。很多人卡在这一步,误以为函数能递归计算,其实它连目录都拒绝读取。
真正要统计整个文件夹,必须手动遍历所有子项,逐个判断是否为文件,再累加大小。
- 用
os.walk()遍历最稳妥:它天然处理嵌套、符号链接(默认跳过)、权限不足目录(可捕获异常) - 避免用
os.listdir()+os.path.join()手写递归:容易漏掉深层嵌套,或在遇到权限错误时直接崩溃 -
pathlib.Path.rglob("*")更现代,但对大目录性能略低,且默认不区分文件/目录,需额外.is_file()过滤
统计过程必须捕获 PermissionError 和 OSError
实际扫描时,os.walk() 会进入系统目录(如 /proc、/sys)或用户无权访问的子目录,此时 os.path.getsize() 或 os.stat() 直接抛异常,不捕获就会中断整个统计。
正确做法是在内层循环中 try/catch,跳过问题项,而不是让程序崩掉:
立即学习“Python免费学习笔记(深入)”;
for root, dirs, files in os.walk(top_path):
for f in files:
fp = os.path.join(root, f)
try:
total += os.path.getsize(fp)
except (PermissionError, OSError):
continue # 忽略无法读取的文件,继续下一个os.path.getsize() 返回字节数,别直接当 MB 显示
返回值是纯整数(单位字节),直接除以 1024 得到的是 KiB,不是 KB;除以 1000 是错的,不符合二进制存储惯例。更关键的是:大目录结果可能超 int 范围(虽然 Python int 无上限,但显示时易读性差)。
- 建议统一转为 MiB(1 MiB = 1024 × 1024 字节),保留一位小数:
round(total / (1024**2), 1) - 若需兼容人类习惯,可用
humanize.naturalsize(total, binary=True),但需额外装包,非标准库 - 注意 Windows 下 NTFS 稀疏文件、压缩文件的实际磁盘占用 ≠
getsize()值,该函数返回逻辑大小,不是磁盘占用
Windows 下长路径报错:需要启用长路径支持或改用 pathlib
Windows 默认限制路径长度 260 字符,os.path.getsize() 遇到超长路径会抛 FileNotFoundError 或 OSError: [WinError 206] The filename or extension is too long。
- 临时方案:在脚本开头加
import os; os.environ["PYTHONIOENCODING"] = "utf-8"无效,真正要改注册表或组策略启用长路径 - 更可靠方案:改用
pathlib.Path,它在 Python 3.8+ 对长路径支持更好,且异常类型更明确(FileNotFoundError可单独捕获) - 不要依赖
\?前缀硬拼路径——容易出错,且os.walk()不自动适配
实际跑起来最稳的组合就是 os.walk() + 内层 try/except + 字节转 MiB。路径深度、特殊字符、权限、长名——这些不是边缘情况,而是日常必然遇到的点,漏掉任意一个,脚本在真实环境里就等于没写。


















