在Python中获取一个文件或目录(文件夹)的大小

商业

使用Python标准库os,你可以得到一个文件的大小(容量)或一个目录中包含的文件的总大小。

下面解释三种方法。可以得到的大小单位都是字节。

  • 获取文件的大小:os.path.getsize()
  • 通过结合以下函数获得一个目录的大小(Python 3.5或更高版本):os.scandir()
  • 结合以下函数来获得目录的大小(Python 3.4和更早的版本):os.listdir()

获取文件的大小: os.path.getsize()

文件的大小(容量)可以通过os.path.getsize()获得。

给出你想得到的文件大小的路径作为参数。

import os

print(os.path.getsize('data/src/lena_square.png'))
# 473831

获取一个目录(文件夹)的大小: os.scandir()

要计算一个目录(文件夹)中包含的文件的总大小,使用os.scandir()。

这个函数是在Python 3.5中添加的,所以早期版本使用os.listdir()。os.listdir()的例子将在后面描述。

定义一个函数如下。

def get_dir_size(path='.'):
    total = 0
    with os.scandir(path) as it:
        for entry in it:
            if entry.is_file():
                total += entry.stat().st_size
            elif entry.is_dir():
                total += get_dir_size(entry.path)
    return total

print(get_dir_size('data/src'))
# 56130856

os.scandir()返回一个os.DirEntry对象的迭代器。

DirEntry 对象,使用 is_file() 和 is_dir() 方法来确定它是一个文件还是一个目录。如果它是一个文件,其大小从stat_result对象的st_size属性中获得。在目录的情况下,这个函数被递归调用,将所有的大小相加并返回总的大小。

此外,默认情况下,is_file()对文件的符号链接返回TRUE。同时,is_dir()对目录的符号链接返回true。如果你想忽略符号链接,请将is_file()和is_dir()的 follow_symlinks 参数设置为false。

另外,如果你不需要遍历子目录,你可以直接删除以下部分。

            elif entry.is_dir():
                total += get_dir_size(entry.path)

如果文件的路径作为参数被传递,上述函数将失败。如果你需要一个函数来返回一个文件或一个目录的大小,你可以写如下。

def get_size(path='.'):
    if os.path.isfile(path):
        return os.path.getsize(path)
    elif os.path.isdir(path):
        return get_dir_size(path)

print(get_size('data/src'))
# 56130856

print(get_size('data/src/lena_square.png'))
# 473831

获取一个目录(文件夹)的大小: os.listdir()

在Python 3.4或更早的版本中没有os.scandir(),所以使用os.listdir()。

定义一个函数如下。

def get_dir_size_old(path='.'):
    total = 0
    for p in os.listdir(path):
        full_path = os.path.join(path, p)
        if os.path.isfile(full_path):
            total += os.path.getsize(full_path)
        elif os.path.isdir(full_path):
            total += get_dir_size_old(full_path)
    return total

print(get_dir_size_old('data/src'))
# 56130856

其基本思想与os.scandir()的情况相同。

用os.listdir()可以得到的是一个文件名(目录名)的列表。每个文件名或目录名与父目录的路径用os.path.join()连接起来,以创建全路径。

如果目标是一个符号链接,os.path.isfile()和os.path.isdir()将判断实体。所以,如果你想忽略符号链接,请结合os.path.islink()使用条件判断,它对符号链接返回true。

与os.scandir()的情况一样,如果你不需要遍历子目录,只需删除下面的部分。

        elif os.path.isdir(full_path):
            total += get_dir_size_old(full_path)

如果文件的路径作为参数被传递,上述函数将失败。如果你需要一个函数来返回一个文件或一个目录的大小,你可以写如下。

def get_size_old(path='.'):
    if os.path.isfile(path):
        return os.path.getsize(path)
    elif os.path.isdir(path):
        return get_dir_size_old(path)

print(get_size_old('data/src'))
# 56130856

print(get_size_old('data/src/lena_square.png'))
# 473831