本文将深入探讨如何利用 Python 编程语言来检测文件或文件夹的大小。
Python 是一种多用途编程语言,用途广泛。 它不仅能构建小型命令行工具,还能开发复杂的 Web 应用程序。
其中一个常被低估的功能是它与操作系统交互的能力。 通过 Python 管理操作系统操作,可以显著节省自动化流程的创建时间。
让我们深入了解 Python 如何与操作系统协同工作。
Python 与操作系统交互的方式
没有任何程序能够完全独立于其运行环境。 对于 Python 而言,与操作系统交互是完成许多任务的基础。
Python 提供了几个模块来实现与操作系统的交互。 其中最常用的是 os、sys、pathlib 和 subprocess。
这些模块都是 Python 内置的,因此无需使用 PIP 安装。 可以使用以下语句导入它们:
import os import sys import pathlib import subprocess
以下列表概述了每个导入模块的主要功能:
- os:提供一种与系统特定的功能(根据你的操作系统而变化)进行交互的可移植方法。 除非需要更高级的功能,否则通常它是首选模块。
- sys:包含系统特定的参数和函数。 此模块允许访问解释器变量和函数。 os 模块侧重于与操作系统交互,而 sys 则侧重于与 Python 解释器交互。
- pathlib:用于高级路径操作。 它允许将文件系统表示为对象,并为每个操作系统提供相应的语义。
- subprocess:允许直接从 Python 执行子进程和管理子进程。 这包括使用标准输入、标准输出和返回码。 你可以参考我们关于 Python 子进程的指南了解更多信息。
根据具体需求,还有一些更专业的库提供更具体的功能。 但在大多数情况下,上述模块足够满足要求。
请注意,这些模块提供的大部分功能会因操作系统而异。 请记住,UNIX 系统通常与 Python 具有最佳兼容性。
现在你已经对 Python 如何与操作系统交互有了初步了解,接下来我们来看看如何检查文件和文件夹的大小。 所有以下解决方案都可以在 Python 中的文件和文件夹大小 GitHub 仓库中找到。
利用 os.stat().st_size
在这种方法中,我们将使用 os 模块的 stat() 函数。 此函数返回关于特定路径的各种信息。
提示:os.path.getsize() 函数也可以完成相同的工作。 但是,使用 os.stat().st_size 的优势在于它不遵循符号链接。
在继续之前,我们先创建一个名为 lorem.txt 的测试文件,并在其中粘贴一些占位文本。 可以访问 Lorem Ipsum 文本生成器,并将生成的文本粘贴到 lorem.txt 文件中。
在同一目录下,创建一个名为 method1.py 的文件,并将以下代码粘贴进去:
import os size = os.stat('lorem.txt').st_size print(size)
让我们分析一下这段代码的作用:
- 第一行导入 os 模块。
- 变量 size 存储 lorem.txt 文件的大小。
- os.stat() 函数返回与文件相关的大量信息。
- st_size 属性表示文件的大小。
- 打印 size 变量。
尝试运行这个 Python 脚本。 根据 lorem.txt 文件的内容,你会得到不同的结果。
输出:
20064
输出以字节为单位。 这不便于阅读,因此让我们将其转换为更易于理解的格式,以便更好地了解文件的大小。
首先,安装 humanize 包,可以通过在 shell 中运行以下命令来安装:
pip install humanize
然后,可以使用 naturalsize() 函数将字节值转换为人类可读的文件大小,例如 KB、MB、GB 或 TB。
import os from humanize import naturalsize size = os.stat('lorem.txt').st_size print(size) print(naturalsize(size))
上面的代码首先以字节为单位打印文件大小,然后以更易读的格式打印结果。
输出:
20064 20.1 kB
使用 pathlib 库
虽然 pathlib 库主要用于路径操作,但它也将其他模块的一些有用功能作为 Path 对象(Path 类的实例)的方法组合在一起。
创建一个名为 method2.py 的文件,并导入 Path 类。
from pathlib import Path
然后,创建一个 Path 对象,将 lorem.txt 文件的路径作为参数传递。
file_ = Path('lorem.txt')
现在,你可以访问 Path 类的 stat() 方法。 它的工作方式与 os.stat() 函数相同,因此你同样可以打印文件的大小。
print(file_.stat().st_size)
输出:
20064
如你所见,我们得到了与第一种方法相同的结果。 上面的结果也以字节格式打印,因此我们可以使用 humanize 模块使其更具可读性。
from pathlib import Path from humanize import naturalsize size = Path('lorem.txt').stat().st_size print(naturalsize(size))
此代码产生以下输出:
20.1 kB
使用子进程执行 Unix 命令
subprocess 模块允许从 Python 调用和管理子进程。 因此,我们可以运行任何命令并直接在 Python 中处理其输出。
提示:此方法仅适用于运行 Unix 操作系统(Linux、Mac)的情况。
打开一个名为 method3.py 的文件,并将以下代码粘贴进去:
from subprocess import run process = run(['du', 'lorem.txt'], capture_output=True, text=True) print(process.stdout)
让我们详细分析一下这段代码:
- 我们从 subprocess 模块导入 run 函数。
- 变量 process 包含运行命令 du lorem.txt 的结果。
- du 是一个 Linux 实用工具,它允许我们获取文件的磁盘空间使用情况。
- capture_output 使我们能够访问 stdout(标准输出)属性。
- text 表示我们将输出存储为字符串而不是字节。
- 我们打印进程的标准输出。
如果运行上面的代码,你会得到以下输出:
20 lorem.txt
如你所见,它提供了文件的大小和名称。 如果只想获取文件的大小,则需要拆分输出(记住它是一个字符串)并打印第一个元素。
from subprocess import run process = run(['du', 'lorem.txt'], capture_output=True, text=True) size = process.stdout.split()[0] print(size)
输出:
20
此输出仍然不便于阅读。 我们可以推断出度量单位是 KB(从之前的方法可以知道),但无法直接确定文件的大小。
为了解决这个问题,我们可以使用 -h (人类可读) 标志。
提示:可以通过运行 man du 或 du –help 来获取此命令的手册。
from subprocess import run process = run(['du', '-h', 'lorem.txt'], capture_output=True, text=True) size = process.stdout.split()[0] print(size)
现在,这个脚本的输出更具可读性:
20K
如果你想了解更多关于 subprocess 模块及其应用,请参考我们关于 Python 子进程的指南。
递归获取文件夹的大小
如果要获取文件夹的大小,需要遍历目录及其子目录中存在的每个文件。 我们将使用两种方法来完成此操作:
- 使用 pathlib 遍历路径。
- 结合子进程使用 du 命令。
以下代码将使用我主文件夹中一个名为 tests 的目录的路径。 你需要将该路径替换为你想要获取大小的目录的实际路径。
使用 pathlib 遍历路径
让我们看看如何通过遍历文件来获取目录的大小。
from pathlib import Path from humanize import naturalsize def get_size(path="."): size = 0 for file_ in Path(path).rglob('*'): size += file_.stat().st_size return naturalsize(size) test_path = Path.home() / 'Documents/tests/' print(get_size(test_path))
这段代码看起来可能有些复杂,我们来分解一下每一部分的作用。
- 导入 Path 类和 naturalsize() 函数。
- 定义一个带有 path 参数的 get_size() 函数,默认指向当前目录。
- size 变量只是一个占位符,用于累加每个文件的大小。
- 遍历路径中的每个文件。
- 获取每个文件的大小并将其添加到 size 变量中。
- 以人类可读的格式返回 size 变量。
当然,我使用的是只有我的机器上才存在的目录进行测试。 不要忘记将路径更改为你计算机上存在的文件夹。
对于我的情况,我得到以下输出:
403.4 MB
使用子进程执行 du 命令
此方法具有以下优点:
- 结果更准确。
- 速度更快。
from subprocess import run from pathlib import Path test_path = Path.home() / 'Documents/tests/' process = run(['du', '-sh', test_path], capture_output=True, text=True) size = process.stdout.split()[0] print(size)
我们使用与方法 3 类似的方法,但是这次我们获取的是目录的大小,而不是文件的大小。
输出:
481M
如你所见,这两种获取文件夹大小的方法返回的结果略有不同。 目录越大,你获得的差异就越大。
在 pathlib 或 subprocess 方法之间选择取决于你。 如果你知道每次都会使用 Linux,则可以使用子进程解决方案;否则,可以使用 pathlib 解决方案。
总结
在与操作系统交互时,Python 非常实用。 你可以使用 Python 实现自动化流程并节省大量时间。 与操作系统交互的主要模块是 os、sys、path 和 subprocess。
在本教程中,你学习了:
- Python 如何与操作系统交互。
- 使用内置模块执行操作系统操作。
- 如何使用 humanize 模块打印人类可读的大小。
- 使用 3 种方法计算文件的大小。
- 如何递归地或使用 du 命令计算目录的大小。