在我重新发明这个特殊的轮子之前,有没有人有一个很好的用Python计算目录大小的例程?如果该例程能以Mb/Gb等格式格式化大小,那就太好了。
当前回答
我在这里有点晚(和新),但我选择使用subprocess模块和Linux中的'du'命令行来检索文件夹大小的准确值,单位为MB。我必须使用if和elif用于根文件夹,否则子进程会由于返回的非零值而引发错误。
import subprocess
import os
#
# get folder size
#
def get_size(self, path):
if os.path.exists(path) and path != '/':
cmd = str(subprocess.check_output(['sudo', 'du', '-s', path])).\
replace('b\'', '').replace('\'', '').split('\\t')[0]
return float(cmd) / 1000000
elif os.path.exists(path) and path == '/':
cmd = str(subprocess.getoutput(['sudo du -s /'])). \
replace('b\'', '').replace('\'', '').split('\n')
val = cmd[len(cmd) - 1].replace('/', '').replace(' ', '')
return float(val) / 1000000
else: raise ValueError
其他回答
这有点晚了,但只要安装了glob2和humanize,就行了。注意,在Python 3中,默认的iglob具有递归模式。如何修改Python 3的代码是留给读者的简单练习。
>>> import os
>>> from humanize import naturalsize
>>> from glob2 import iglob
>>> naturalsize(sum(os.path.getsize(x) for x in iglob('/var/**'))))
'546.2 MB'
这将遍历所有子目录;文件大小总和:
import os
def get_size(start_path = '.'):
total_size = 0
for dirpath, dirnames, filenames in os.walk(start_path):
for f in filenames:
fp = os.path.join(dirpath, f)
# skip if it is symbolic link
if not os.path.islink(fp):
total_size += os.path.getsize(fp)
return total_size
print(get_size(), 'bytes')
和一个在线的乐趣使用操作系统。listdir(不包括子目录):
import os
sum(os.path.getsize(f) for f in os.listdir('.') if os.path.isfile(f))
参考:
os.path.getsize -以字节为单位给出大小 os.walk os.path.islink
更新 使用os.path。Getsize,这比使用os.stat()更清楚。st_size方法。
感谢ghostdog74指出这一点!
操作系统。stat - st_size以字节为单位给出大小。也可用于获取文件大小等文件相关信息。
import os
nbytes = sum(d.stat().st_size for d in os.scandir('.') if d.is_file())
更新2018
如果您使用的是Python 3.4或更早版本,那么您可以考虑使用第三方scandir包提供的更有效的walk方法。在Python 3.5及以后版本中,此包已合并到标准库和操作系统中。行走得到了相应的性能提升。
更新2019
最近我越来越多地使用pathlib,这里有一个pathlib解决方案:
from pathlib import Path
root_directory = Path('.')
sum(f.stat().st_size for f in root_directory.glob('**/*') if f.is_file())
不可否认,这有点像黑客,只适用于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])
蒙纳特的答案是很好的,但它失败的符号链接,所以你还必须检查这个路径是否真的存在
if os.path.exists(fp):
total_size += os.stat(fp).st_size
Python 3.6+递归文件夹/文件大小使用os.scandir。和@blakev的回答一样强大,但更短,采用EAFP python风格。
import os
def size(path, *, follow_symlinks=False):
try:
with os.scandir(path) as it:
return sum(size(entry, follow_symlinks=follow_symlinks) for entry in it)
except NotADirectoryError:
return os.stat(path, follow_symlinks=follow_symlinks).st_size
推荐文章
- 如何在交互式Python中查看整个命令历史?
- 如何显示有两个小数点后的浮点数?
- 如何用OpenCV2.0和Python2.6调整图像大小
- 在每个列表元素上调用int()函数?
- 当使用代码存储库时,如何引用资源的相对路径
- 如何在Flask-SQLAlchemy中按id删除记录
- 在Python中插入列表的第一个位置
- Python Pandas只合并某些列
- 如何在一行中连接两个集而不使用“|”
- 从字符串中移除前缀
- 代码结束时发出警报
- 如何在Python中按字母顺序排序字符串中的字母
- 在matplotlib中将y轴标签添加到次要y轴
- 如何消除数独方块的凹凸缺陷?
- 为什么出现这个UnboundLocalError(闭包)?