
本文详细介绍了如何使用 Python 准确计算文件在磁盘上的实际占用空间(Size on Disk),而非其逻辑大小。通过利用 `os.lstat` 和 `os.statvfs` 获取文件系统块大小,并结合文件大小进行向上取整计算,确保在创建固定大小镜像等场景中避免空间不足问题。文章还提供了性能优化方案和重要注意事项。
在文件系统中,我们通常会遇到两种大小概念:
对于需要精确控制存储空间的场景,例如使用 dd 命令创建固定大小的磁盘镜像,或者评估存储介质的实际利用率时,了解文件的“磁盘占用大小”至关重要。如果仅依据逻辑大小进行预分配,可能会因实际占用空间超出预期而导致“空间不足”错误。
Python 标准库提供了获取文件和文件系统元数据的方法,我们可以利用这些信息来计算文件的实际磁盘占用。核心思路是:
立即学习“Python免费学习笔记(深入)”;
以下是一个用于计算常规文件在磁盘上实际占用空间的 Python 函数:
import os
import stat
def size_on_disk(path: str) -> int:
"""
计算常规文件在磁盘上的实际占用空间(Size on Disk)。
Args:
path (str): 文件的路径。
Returns:
int: 文件在磁盘上的实际占用字节数。
Raises:
NotImplementedError: 如果路径不是常规文件(例如目录、符号链接)。
"""
# 1. 获取文件状态信息
st = os.lstat(path)
# 2. 检查文件类型:仅支持常规文件
if not stat.S_ISREG(st.st_mode):
raise NotImplementedError(f"路径 '{path}' 不是常规文件,此函数仅支持常规文件。")
# 3. 获取文件系统状态信息,以获取块大小
# f_frsize 是文件系统分配单元(fragment size),通常等同于块大小
st_vfs = os.statvfs(path)
block_size = st_vfs.f_frsize
# 4. 计算文件占用的块数
# divmod(a, b) 返回 (a // b, a % b)
n_blocks, rem_bytes = divmod(st.st_size, block_size)
# 如果有余数,说明文件内容需要额外一个块来存储
# bool(rem_bytes) 在 rem_bytes > 0 时为 True (转换为 1),否则为 False (转换为 0)
total_blocks = n_blocks + bool(rem_bytes)
# 5. 计算实际磁盘占用大小
return total_blocks * block_size
代码解析:
在使用上述函数时,请务必注意以下限制和行为:
os.statvfs() 调用会查询文件系统,这可能是一个相对耗时的操作。如果您的程序需要对同一卷(磁盘分区)上的大量文件重复调用 size_on_disk 函数,可以考虑缓存 os.statvfs 的结果,以避免重复查询。
文件系统设备 ID (st.st_dev) 可以作为缓存键,因为同一设备上的所有文件共享相同的 statvfs 信息。
import os
import stat
# 全局缓存字典,用于存储文件系统设备ID到statvfs对象的映射
STATVFS_CACHE = {}
def size_on_disk_cached(path: str) -> int:
"""
计算常规文件在磁盘上的实际占用空间(Size on Disk),并缓存文件系统信息以提高性能。
Args:
path (str): 文件的路径。
Returns:
int: 文件在磁盘上的实际占用字节数。
Raises:
NotImplementedError: 如果路径不是常规文件。
"""
st = os.lstat(path)
if not stat.S_ISREG(st.st_mode):
raise NotImplementedError(f"路径 '{path}' 不是常规文件,此函数仅支持常规文件。")
# 使用文件的设备ID作为缓存键
# 如果缓存中不存在,则调用 os.statvfs 并存储结果
if not (st_vfs := STATVFS_CACHE.get(st.st_dev)):
STATVFS_CACHE[st.st_dev] = (st_vfs := os.statvfs(path))
block_size = st_vfs.f_frsize
n_blocks, rem_bytes = divmod(st.st_size, block_size)
return (n_blocks + bool(rem_bytes)) * block_size
通过使用 STATVFS_CACHE 字典,当函数被多次调用处理位于同一文件系统(即具有相同 st.st_dev)的文件时,os.statvfs 将只被调用一次,显著提高了性能。
本文提供了一种使用 Python 准确计算常规文件在类 Unix 系统上“磁盘占用大小”的方法。通过理解文件系统块分配机制,并结合 os.lstat 和 os.statvfs,我们可以得到比文件逻辑大小更真实的磁盘占用估算。虽然该方法存在特定限制(如仅限于常规文件、类 Unix 系统、不包含所有元数据),但对于需要精确空间预估的场景(如创建磁盘镜像)而言,它提供了一个实用且高效的解决方案。在实际应用中,尤其是在处理大量文件时,利用缓存机制可以进一步优化性能。
以上就是使用 Python 计算文件在磁盘上的实际占用空间(Size on Disk)的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号