如何使用Python检查文件和文件夹大小?
在本篇文章中,您将学会使用Python来检查文件或文件夹的大小。
Python是最具多功能的编程语言之一。借助它,您可以从一个小的命令行界面(CLI)程序到一个complex web application的程序。
然而,它最被低估的功能之一是与操作系统进行交互的能力。使用Python管理操作系统操作可以节省大量时间,尤其是在创建自动化流程时。
让我们看看Python如何与操作系统进行交互。
Python如何与操作系统进行交互?
没有人能与环境隔离生活。这在Python中也适用,有时与操作系统进行交互以完成任务是至关重要的。
Python有几个与操作系统进行交互的模块。最常用的是os、sys、pathlib和subprocess。
由于它们是内置模块,您无需使用PIP安装它们。您可以使用以下语句导入它们:
import os
import sys
import pathlib
import subprocess
下面的列表指示了这些导入的主要功能:
- Os:以可移植的方式使用特定于系统(取决于您的操作系统)的功能。在大多数情况下,这是正确的选择,除非您需要更高级的功能
- Sys:特定于系统的参数和函数。该模块提供对解释器变量和函数的访问。os模块与操作系统进行交互,sys模块与Python解释器进行交互
- Pathlib:高级路径使用。它允许您将文件系统表示为对象,并为每个操作系统提供相应的语义。
- Subprocess:直接从Python执行和管理子进程。这涉及使用stdin、stdout和返回代码。您可以通过阅读我们的Python subprocess guide来了解更多信息。
根据您的需求,还有一些高级库包含更具体的功能。然而,大多数情况下,您可以使用上述模块进行开发。
注意:这些模块提供的大多数函数的输出将根据您的操作系统而有所不同。请记住,通常最佳匹配是链接_5和Python。
现在,您对Python如何与操作系统进行交互有了一个简单的了解,让我们来看看检查文件和文件夹大小的方法。以下所有解决方案都可以在链接_6的GitHub存储库中找到。
使用os.stat().st_size
在这种方法中,我们将使用os模块的stat()函数。它返回有关特定路径的许多信息。
注意:使用os.path.getsize()函数也可以完成任务。使用os.stat().st_size的优势在于它不会遵循符号链接。
在继续之前,让我们创建一个名为lorem.txt的测试文件,在其中我们将粘贴一些愚蠢的文本。我们可以访问链接_8并将文本粘贴到lorem.txt文件中。
在同一目录中,创建一个名为method1.py的文件,并粘贴以下代码:
import os
size = os.stat('lorem.txt').st_size
print(size)
让我们逐步解析一下这段代码:
- 在第一行,我们导入了os模块
- size变量包含文件lorem.txt的大小
- os.stat()函数返回与文件相关的一些信息
- st_size属性表示文件的大小
- 我们打印出size变量
尝试。根据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
虽然pathlib专门用于与路径一起工作,但它将其他模块的一些有用函数作为Path对象的方法(Path类的实例)。
创建一个名为method2.py的文件,并导入Path class。
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命令:
子进程模块允许我们从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 function
- 变量process包含运行命令du lorem.txt的结果
- du是一个允许我们获取文件的磁盘空间的Linux实用程序
- capture_output使我们可以访问标准输出(standard 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 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 subprocess guide。
递归获取文件夹的大小
如果你想获取文件夹的大小,你需要遍历目录中的每个文件以及其子目录。我们将使用两种方法来实现:
- 使用pathlib遍历路径
- 使用subprocess执行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()函数
- 定义get_size()函数,其中参数path默认指向当前目录
- size变量只是一个占位符,我们将在其中添加每个文件的大小
- 遍历路径中的每个文件
- rglob()方法递归返回与模式匹配的文件
-
rglob(‘*'),表示获取目录中的所有文件
- 获取每个文件的大小并将其添加到size变量中
- 以人类可读的方式返回size变量
当然,我正在使用一个仅在我的计算机上可用的目录进行测试。不要忘记将路径更改为计算机上存在的文件夹。
在我的情况下,我得到了以下输出:
403.4 MB
使用subprocess执行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,可以使用 subprocess,否则可以使用pathlib解决方案。
总结
Python在与操作系统交互时非常方便。您可以使用 Python 自动化流程,并节省大量时间。与操作系统交互的主要模块是os、sys、path和subprocess。
在本教程中,您学到了:
- Python如何与操作系统交互
- 使用内置模块进行操作系统操作的方法
- 如何使用 humanize 模块打印可读性强的结果
- 使用3种方法计算文件的大小
- 递归计算目录大小或使用 du 命令计算目录大小