Python文件大小案例如何获取尺寸

wen python案例 21

Python文件大小获取方法:从基础到高级案例详解

📖 目录导读

  1. 为什么需要获取文件大小?
  2. Python获取文件尺寸的核心方法
    • 1 os.path.getsize()
    • 2 os.stat() 与 stat模块
    • 3 pathlib 的 Path.stat()
  3. 实战案例:不同场景下的文件大小获取
    • 1 单文件大小检测
    • 2 文件夹内所有文件大小统计
    • 3 大文件分片读取尺寸验证
  4. 常见问题与避坑指南(Q&A)
  5. 性能优化与最佳实践
  6. 选择最适合你的方法

为什么需要获取文件大小?

在数据清洗、日志管理、文件传输、磁盘空间监控等场景中,准确获取文件大小是基础操作。

Python文件大小案例如何获取尺寸

  • 磁盘清理工具:需要遍历文件夹并删除超过指定大小的日志文件。
  • 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 pathlibPath.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_sizegetsize都返回Python的int,无大小限制,但在32位Python上,st_size可能因off_t类型限制只能表示2GB以内文件,解决方案:升级到64位Python,或使用os.open() + 低层lseek(不推荐)。

Q2: 为什么获取的“文件大小”与资源管理器显示不同?

A: 可能原因:

  1. 磁盘扇区占用:文件系统最小分配单元(如4KB),小文件实际占用空间可能大于文件大小。
  2. 硬链接:同一个inode被多个文件名指向,统计时可能重复计算。
  3. 稀疏文件:文件中存在大量空字节,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 性能提升显著
检查文件是否存在后获取大小 pathlibexists() + stat() 避免异常

核心原则

  • 始终捕获FileNotFoundErrorPermissionError
  • 对于远程文件,优先使用HEAD请求而非下载
  • 可读性优先于微优化,除非是性能关键路径

延伸思考
如果你需要统计目录树的总占用空间,推荐os.path.getsize()配合递归,或使用shutil.disk_usage()获取磁盘整体使用情况,对于极大规模文件系统(百万级文件),考虑pyfilesystem2或直接调用系统API(du命令的Python封装)。

你可以根据上述案例,快速构建自己的文件尺寸监控工具了!

抱歉,评论功能暂时关闭!