在我重新发明这个特殊的轮子之前,有没有人有一个很好的用Python计算目录大小的例程?如果该例程能以Mb/Gb等格式格式化大小,那就太好了。


当前回答

你可以这样做:

import commands   
size = commands.getoutput('du -sh /path/').split()[0]

在这种情况下,我没有在返回之前测试结果,如果你想要,你可以用commands.getstatusoutput检查它。

其他回答

import os

def get_size(path):
    total_size = 0
    for dirpath, dirnames, filenames in os.walk(path):
        for f in filenames:
            if os.path.exists(fp):
                fp = os.path.join(dirpath, f)
                total_size += os.path.getsize(fp)

    return total_size   # in megabytes

谢谢monkut & troex!

你可以这样做:

import commands   
size = commands.getoutput('du -sh /path/').split()[0]

在这种情况下,我没有在返回之前测试结果,如果你想要,你可以用commands.getstatusoutput检查它。

不可否认,这有点像黑客,只适用于Unix/Linux。

它匹配du -sb。因为实际上这是一个Python bash包装器,它运行du -sb。命令。

import subprocess

def system_command(cmd):
    """"Function executes cmd parameter as a bash command."""
    p = subprocess.Popen(cmd,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         shell=True)
    stdout, stderr = p.communicate()
    return stdout, stderr

size = int(system_command('du -sb . ')[0].split()[0])

Du默认情况下不遵循符号链接。这里没有答案,使用follow_symlinks=False。

下面是一个遵循du默认行为的实现:

def du(path) -> int:
    total = 0
    for entry in os.scandir(path):
        if entry.is_file(follow_symlinks=False):
            total += entry.stat().st_size
        elif entry.is_dir(follow_symlinks=False):
            total += du(entry.path)
    return total

测试:

class Test(unittest.TestCase):
    def test_du(self):
        root = '/tmp/du_test'
        subprocess.run(['rm', '-rf', root])
        test_utils.mkdir(root)
        test_utils.create_file(root, 'A', '1M')
        test_utils.create_file(root, 'B', '1M')
        sub = '/'.join([root, 'sub'])
        test_utils.mkdir(sub)
        test_utils.create_file(sub, 'C', '1M')
        test_utils.create_file(sub, 'D', '1M')
        subprocess.run(['ln', '-s', '/tmp', '/'.join([root, 'link']), ])
        self.assertEqual(4 << 20, util.du(root))

到目前为止,建议的一些方法实现了递归,其他方法使用shell或不会生成格式整齐的结果。当您的代码对于Linux平台是一次性的,您可以像往常一样获得格式化,包括递归,作为一行程序。除了最后一行的输出,它将适用于当前版本的python2和python3:

du.py
-----
#!/usr/bin/python3
import subprocess

def du(path):
    """disk usage in human readable format (e.g. '2,1GB')"""
    return subprocess.check_output(['du','-sh', path]).split()[0].decode('utf-8')

if __name__ == "__main__":
    print(du('.'))

简单,高效,将工作于文件和多级目录:

$ chmod 750 du.py
$ ./du.py
2,9M