Python文件大小获取方法:从基础到高级案例详解
📖 目录导读
- 为什么需要获取文件大小?
- Python获取文件尺寸的核心方法
- 1 os.path.getsize()
- 2 os.stat() 与 stat模块
- 3 pathlib 的 Path.stat()
- 实战案例:不同场景下的文件大小获取
- 1 单文件大小检测
- 2 文件夹内所有文件大小统计
- 3 大文件分片读取尺寸验证
- 常见问题与避坑指南(Q&A)
- 性能优化与最佳实践
- 选择最适合你的方法
为什么需要获取文件大小?
在数据清洗、日志管理、文件传输、磁盘空间监控等场景中,准确获取文件大小是基础操作。

- 磁盘清理工具:需要遍历文件夹并删除超过指定大小的日志文件。
- web应用上传限制:需要校验用户上传的文件是否超过服务器阈值。
- 大文件分块上传:需要知道文件总大小来切割成合理分片。
Python提供了多种获取文件尺寸的函数,本文将结合真实案例,从标准库到pathlib现代写法,全面解析如何高效获取文件大小,并附上避坑指南。
Python获取文件尺寸的核心方法
1 os.path.getsize() — 最简洁的单文件方案
import os
file_path = "example.txt"
size_in_bytes = os.path.getsize(file_path)
print(f"文件大小:{size_in_bytes} 字节")
优点:一行代码,无需额外导入。
缺点:若文件不存在会抛出FileNotFoundError,需配合异常处理。
案例:获取文件并以可读格式输出
def get_file_size_human(path):
try:
size = os.path.getsize(path)
for unit in ['B', 'KB', 'MB', 'GB']:
if size < 1024:
return f"{size:.2f} {unit}"
size /= 1024
return f"{size:.2f} TB"
except FileNotFoundError:
return "文件不存在"
2 os.stat() 与 stat 模块 — 获取完整文件元数据
当需要同时获取大小、修改时间、权限等信息时,使用os.stat():
import os
import stat
file_stat = os.stat("report.log")
file_size = file_stat.st_size # 字节为单位的整数
permissions = stat.filemode(file_stat.st_mode) # '-rw-r--r--'
优势:一次系统调用获取全部元数据,适合批量处理。
注意:st_size返回以字节为单位的整数,对于大于2GB的文件,在32位Python中可能溢出(现代64位系统无此问题)。
3 pathlib 的 Path.stat() — 面向对象与现代写法
Python 3.4+推荐的路径操作库,代码更直观:
from pathlib import Path
p = Path("data.csv")
size = p.stat().st_size # 与os.stat()相同
也可以直接调用便捷方法:
# 需Python 3.6+ size = p.stat().st_size
为什么推荐pathlib?
- 跨平台路径处理(自动处理Windows反斜杠)
- 链式调用(如
Path.cwd().parent / "output") - 与
os模块互操作性强
实战案例:不同场景下的文件大小获取
1 单文件大小检测(带错误处理)
场景:用户上传文件前检查是否超过100MB。
代码:
import os
from pathlib import Path
def check_upload_size(file_path_str):
path = Path(file_path_str)
if not path.exists():
return "文件路径错误"
size_bytes = path.stat().st_size
max_bytes = 100 * 1024 * 1024 # 100MB
if size_bytes > max_bytes:
return f"文件过大:{size_bytes/1024/1024:.1f}MB > 100MB"
else:
return f"文件尺寸合规:{size_bytes/1024/1024:.1f}MB"
2 文件夹内所有文件大小统计(递归遍历)
场景:统计./logs目录下所有.log文件的总大小。
代码:
import os
from pathlib import Path
def calc_total_log_size(base_dir="logs"):
total = 0
for file in Path(base_dir).rglob("*.log"):
try:
total += file.stat().st_size
except OSError:
print(f"警告:无法访问 {file}")
# 转换为MB
return f"{total / 1024 / 1024:.2f} MB"
# 执行
print(calc_total_log_size())
关键点:rglob()递归匹配,OSError处理权限不足的文件。
3 大文件分片读取时校验尺寸
场景:网络传输中,需要确保分片大小与预期一致。
代码:
import os
def verify_chunk(file_path, chunk_number, expected_chunk_size=1024*1024):
file_size = os.path.getsize(file_path)
# 算出实际应有的分片数
full_chunks = file_size // expected_chunk_size
last_chunk_size = file_size % expected_chunk_size
if chunk_number < full_chunks:
actual_size = expected_chunk_size
elif chunk_number == full_chunks:
actual_size = last_chunk_size
else:
return "分片编号超出范围"
# 实际读取分片验证(略)
return f"第{chunk_number}片应有大小:{actual_size}字节"
常见问题与避坑指南(Q&A)
Q1: os.path.getsize() 对于大文件(>2GB)是否会出错?
A: 在64位Python上不会,st_size和getsize都返回Python的int,无大小限制,但在32位Python上,st_size可能因off_t类型限制只能表示2GB以内文件,解决方案:升级到64位Python,或使用os.open() + 低层lseek(不推荐)。
Q2: 为什么获取的“文件大小”与资源管理器显示不同?
A: 可能原因:
- 磁盘扇区占用:文件系统最小分配单元(如4KB),小文件实际占用空间可能大于文件大小。
- 硬链接:同一个inode被多个文件名指向,统计时可能重复计算。
- 稀疏文件:文件中存在大量空字节,
st_size是逻辑大小,磁盘占用更小。
获取磁盘占用应使用os.stat(path).st_blocks * 512。
Q3: 获取网络文件大小(如HTTP)需要下载吗?
A: 不需要,可发送HEAD请求获取Content-Length头:
import requests
resp = requests.head("https://域名/example.zip")
size = int(resp.headers.get("Content-Length", 0))
print(f"远程文件大小:{size}字节")
注意:并非所有服务器都返回Content-Length。
Q4: Windows上打开的文件无法获取大小怎么办?
A: 其他进程可能锁定了文件,使用try...except PermissionError捕获异常,或使用低层API:
import win32file # 需要pywin32 handle = win32file.CreateFile(...) size = win32file.GetFileSize(handle)
性能优化与最佳实践
批量获取时避免重复系统调用
# ❌ 低效:每个文件单独调用stat
for file in files:
size = file.stat().st_size
# ✅ 高效:一次调用获取所有文件stat
def get_sizes_batch(paths):
return [os.stat(p).st_size for p in paths]
使用os.scandir()替代os.listdir()
import os
def get_folder_sizes(base_dir):
total = 0
with os.scandir(base_dir) as entries:
for entry in entries:
if entry.is_file():
total += entry.stat().st_size # scandir的stat已缓存
return total
os.scandir()返回的DirEntry对象缓存了stat信息,避免额外系统调用。
内存映射大文件时的尺寸获取
import mmap
import os
with open("big_file.dat", "rb") as f:
# 先获取大小
size = os.fstat(f.fileno()).st_size
with mmap.mmap(f.fileno(), size, access=mmap.ACCESS_READ) as mm:
print(f"映射了 {len(mm)} 字节")
选择最适合你的方法
| 场景 | 推荐方法 | 理由 |
|---|---|---|
| 快速获取单个文件大小 | os.path.getsize() |
最简洁 |
| 同时需要修改时间、权限等 | os.stat() 或 pathlib.Path.stat() |
一次调用获取全部信息 |
| 现代Python项目(3.6+) | pathlib.Path.stat() |
面向对象,跨平台更安全 |
| 遍历大量文件(>1000个) | os.scandir() + 缓存stat |
性能提升显著 |
| 检查文件是否存在后获取大小 | pathlib 的 exists() + stat() |
避免异常 |
核心原则:
- 始终捕获
FileNotFoundError和PermissionError - 对于远程文件,优先使用HEAD请求而非下载
- 可读性优先于微优化,除非是性能关键路径
延伸思考:
如果你需要统计目录树的总占用空间,推荐os.path.getsize()配合递归,或使用shutil.disk_usage()获取磁盘整体使用情况,对于极大规模文件系统(百万级文件),考虑pyfilesystem2或直接调用系统API(du命令的Python封装)。
你可以根据上述案例,快速构建自己的文件尺寸监控工具了!