在Python中获取子目录的大小

2 投票
3 回答
4199 浏览
提问于 2025-04-18 15:15

我有一个文件夹,里面有很多子文件夹,子文件夹里可能还有子文件夹。

Folder
+-Sub1
| +-SubSub1
| +-File1
+-Sub2
| +-File2
+-Sub3
| +-File3
| +-File4
+-Sub4
  +-File5
  +-SubSub2
    +-File6

我想要获取每个子文件夹(比如Sub1、Sub2等)的总大小。我还需要获取每个文件夹的名字。例如:

Sub1 is 34 MB
Sub2 is 2893 MB
...

我现在有以下代码:

for r, d, f in os.walk(directory):
    size = sum(getsize(join(r,n)) for n in f) / 1048576
    print size
    for s in d:
        print s

这段代码会先打印出所有文件夹的大小,然后再打印出所有文件夹的名字,因为它们是在不同的循环里。请问我该怎么做才能像上面那样同时打印出大小和名字呢?

3 个回答

1

我在寻找类似的问题时发现了这个问题。受到rjbogz的认可解决方案和Robᵩ的回答的启发,我做了这个。它可以提供一个文件夹中所有内容的大小,包括所有子文件夹里的内容等等。

import os
def get_size(source, total_size):
    total_size_in = total_size
    for item in os.listdir(source):
        itempath = os.path.join(source, item)
        if os.path.isfile(itempath):
            total_size += os.path.getsize(itempath)
        elif os.path.isdir(itempath):
            total_size += get_size(itempath, total_size)
    return total_size - total_size_in


def walk_recursive(directory, level):
    for d in next(os.walk(directory))[1]:
        itempath = os.path.join(directory, d)
        size = get_size(itempath, total_size=0)
        if level == 0:
            path = d
        else:
            path = '\\' + d
        print('    '*level +
              '{:6.2f}'.format(float(size) / 1048576) + ' MB  ' + path)
        path = os.listdir(directory)[0]
        if path:
            for f in [path]:
                itempath2 = os.path.join(directory, f)
                if os.path.isdir(itempath2):
                    walk_recursive(itempath, level + 1)


directory = r"<put_your_dir_path_here>"
walk_recursive(directory, level=0)
1

作为第一步,试试这个:

import os
for r, d, f in os.walk('.'):
    size = sum(os.path.getsize(os.path.join(r,n)) for n in f) / 1048576
    print "{} is {}".format(r, size)

在我的电脑上,结果是这样的:

. is 1
./Sub4 is 1
./Sub4/SubSub2 is 1
./Sub3 is 2
./Sub2 is 1
./Sub1 is 1
./Sub1/SubSub1 is 0

这样至少可以把目录名称和它们对应的大小打印出来。

接下来的步骤,你需要找到一种方法,把子目录的大小加到父目录的大小上。在这个例子中,我使用了一个字典来记住子目录的大小:

import os
dir_sizes = {}
for r, d, f in os.walk('.', False):
    size = sum(os.path.getsize(os.path.join(r,f)) for f in f+d)
    size += sum(dir_sizes[os.path.join(r,d)] for d in d)
    dir_sizes[r] = size
    print "{} is {} MB".format(r, size/2**20)

结果(每个 FileN 是 1 兆字节):

./Sub4/SubSub2 is 1 MB
./Sub4 is 2 MB
./Sub3 is 2 MB
./Sub2 is 1 MB
./Sub1/SubSub1 is 0 MB
./Sub1 is 1 MB
. is 6 MB
0

我最后创建了一个这样的函数:

def get_size(source):
    total_size = 0
    total_size = os.path.getsize(source)
    for item in os.listdir(source):
        itempath = os.path.join(source, item)
        if os.path.isfile(itempath):
            total_size += os.path.getsize(itempath)
        elif os.path.isdir(itempath):
            total_size += get_size(itempath)
    return float(total_size) / 1048576

然后在我的循环里调用了这个函数:

for d in os.walk(directory).next()[1]:
    size = get_size(directory+d)
    print d + ' is ' + str(size) ' MB'

撰写回答