如何在 Python 中检查文件和文件夹大小?

已发表: 2021-06-16

在本文中,您将学习在 Python 中检查文件或文件夹的大小

Python 是最通用的编程语言之一。 有了它,您将能够从小型 CLI(命令行界面)程序构建到复杂的 Web 应用程序。

然而,其最被低估的功能之一是与操作系统交互的能力。 在创建自动化流程时,使用 Python 管理操作系统操作可以为您节省大量时间。

让我们看看 Python 如何与操作系统交互。

Python 如何与操作系统交互?

Python 通过 os、sys、path 和 subprocess 模块与 Os 交互

没有人可以脱离他们的环境而生活。 这也适用于 Python,在 Python 中,有时与操作系统交互以完成工作至关重要。

Python 有几个模块可以让我们与操作系统交互。 最常用的是os、sys、pathlib和subprocess。

由于它们是内置模块,因此您无需使用 PIP 安装它们。 您可以使用以下语句导入所有这些:

 import os import sys import pathlib import subprocess

下面的列表显示了这些导入中的每一个的主要功能:

  • Os:使用系统特定(取决于您的操作系统)功能的便携式方式。 在大多数情况下这是正确的选择,除非您需要更高级的东西
  • Sys:系统特定的参数和功能。 该模块提供对解释器变量和函数的访问。 os 模块与操作系统交互,sys 与 Python 解释器交互
  • Pathlib:高级路径用法。 允许您将文件系统表示为对象,并具有每个操作系统的相关语义。
  • 子进程:直接从 Python 执行和子进程管理。 这涉及使用stdinstdout和返回代码。 您可以通过阅读我们的 Python 子流程指南了解更多信息。

根据您的需要,有一些高级库包含更具体的功能。 但是,大多数情况下,您可以使用上述模块。

注意:这些模块提供的大多数功能将根据您的操作系统具有不同的输出。 请记住,通常情况下,最佳匹配是 UNIX 和 Python。

现在您已经快速掌握了 Python 如何与操作系统交互,让我们进入检查文件和文件夹大小的方法。 Python GitHub 存储库中的文件和文件夹大小中提供了以下所有解决方案

使用 os.stat().st_size

在这个方法中,我们将使用 os 模块中的 stat() 函数。 它返回有关特定路径的大量信息。

注意: os.path.getsize()函数也可以完成工作。 使用os.stat()的优势 st_size是它不遵循 simlinks。

在继续之前,让我们创建一个名为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属性表示文件的大小
  • 我们打印大小变量

尝试运行 Python 脚本。 根据lorem.txt文件的内容,您将获得不同的结果。

输出:

 20064

输出以字节表示。 这根本不可读,所以让我们对其进行人性化,以便我们可以更好地了解文件的大小。

首先,通过在 shell 中运行以下命令来安装 humanize 包:

 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 被设计为专门处理路径,但它结合了其他模块的一些有用函数作为 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使我们可以访问突出(标准输出)属性
    • 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 dudu –help来获取此命令的手册。

 from subprocess import run process = run(['du', '-h', 'lorem.txt'], capture_output=True, text=True) size = process.stdout.split()[0] print(size)

现在这个脚本的输出将更具可读性:

 20K

如果您想了解有关子流程模块和可能的应用程序的更多信息,请查看我们的 Python 子流程指南。

递归获取文件夹的大小

如果要获取文件夹的大小,则需要遍历目录及其子目录中存在的每个文件。 我们将使用两种方法来做到这一点:

  • 使用 pathlib 迭代路径
  • 将 du 命令与子进程一起使用

以下代码将使用我的主文件夹中测试目录的路径。 您需要为要获取大小的目录替换该文件的路径。

使用 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 变量只是一个占位符,我们将在其中添加每个文件的大小
  • 遍历路径的每个文件
    • rglob()方法递归返回匹配模式的文件
    • rglob('*') ,意味着我们正在获取目录中的所有文件
  • 获取每个文件的大小并将其添加到大小变量
  • 以人类可读的方式返回大小变量

当然,我正在使用仅在我的机器中可用的目录来测试该功能。 不要忘记更改计算机上存在的文件夹的路径。

就我而言,我得到以下输出:

 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方法之间做出选择。 如果你知道你会使用Linux每次使用的子进程,否则你可以使用pathlib解决方案。

总结

Python 在与操作系统交互时非常方便。 您可以使用 Python 自动化流程并节省大量时间。 与 os 交互的主要模块是 os、sys、path 和 subprocess。

在本教程中,您学习了:

  • Python 如何与操作系统交互
  • 使用内置模块进行OS操作
  • 如何使用humanize模块打印人类可读的
  • 用 3 种方法计算文件的大小
  • 以递归方式或使用du命令计算目录的大小