最近电脑D盘亮“红灯”,可用空间已经不到10个G。想想也没有下载电视剧、电影等,那到底是什么如此占用空间呢?决定写个脚本,查找出TOP N个最大的文件。
写脚本的时候,发现找最大的文件,很容易写出来,但是写前N个最大文件的时候,就发现不那么顺畅(也许是没用对方法)。
先定义一个文件大小排序函数,rank_list初始是一个空的列表,用来存放前N个最大文件的文件大小值;size 是新获取文件的大小;length 默认是3,表示默认查找出当前目录下最大的3个文件。
函数rank()整体思路为: 当rank_list为空时,会根据length入参生成一个与length长度一致的列表rank_list;当rank_list不为空时,根据算法会将传入的size与 rank_list中的各个值(从小到达)进行比较。若size大于某个值A,则处理列表移除原值A,并用size顶替A值原位置(index)。函数最终返回 rank_list 与 size。若rank_list数据有更新,size为被移除的数值(A)的文件大小(单位byte),否则 size = False。
程序如下:
def rank(rank_list,size,length=3):
"""Return rank_list and size,if size is False then rank_list is not updated,
others are updated. Size will be returned which was removed."""
is_update = False
if length < 3:
length = 3
if not len(rank_list):
for i in range(length):
rank_list.append(i)
for i in range(length):
each = rank_list[length-1-i]
if size >= each:
continue
# 排除入参size是最小的情况
elif each != rank_list[-1]:
rank_list.insert(rank_list.index(each)+1,size)
size = rank_list.pop(-1)
return rank_list,size
# 处理入参size是最小的情况
else:
return rank_list,is_update
# 处理入参size是最大的情况
rank_list.insert(0,size)
size = rank_list.pop(-1)
return rank_list,size
由于用os.path.getsize()方法返回的文件大小是byte 字节,为了便于读取,使用humanble_size()函数。如下:
def humanble_size(size):
"""For Readding Easy!"""
if size > 1024: # Kb
size /= 1024
if size > 1024: # Mb
size /= 1024
if size > 1024: # Gb
size /= 1024
return str(round(size,2))+"Gb"
else:
return str(round(size,2)) + "Mb"
else:
return str(round(size,2))+"Kb"
else:
return str(round(size,2))+"bytes"
主程序定义了exclusive_dir(不需要去检查的文件目录),rank_list (存放文件大小值),rank_dic(将文件大小与文件所在的绝对路径对应)。通过os.walk()方法,先移除不需要检查的目录,而后获得当前目录下的各文件与rank_list 中的值大小进行比较,若rank_list 有更新,则设置文件传入的size为键,文件所在的路径为值存于rank_dic ,并删除rand_dic中键为rank()方法返回的size值。最后根据rank_dic 的键值进行排序,输出前Top_N个最大文件的路径与文件大小。
代码如下:
import os,sys
from os.path import join, getsize
if __name__ == "__main__":
try:
path = sys.argv[1]
top_N = sys.argv[2]
except:
path = os.getcwd()
top_N = 10
exclusive_dir = ["iSeeRobotAdvisor","LightInvesting2","VM INSTALL","VIPSTU"]
rank_list = list()
rank_dic = dict()
# topdown=True 则可更改dirnames列表(删除或者分割列表),walk方法紧会递归进入仍在dirnames列表中的目录;
# topdown=False 则无论对dirnames列表如何处理,递归子目录会重新生成,不会改变
for dirpath, dirnames, filenames in os.walk(top=path,topdown=True):
for each in exclusive_dir:
if each in dirnames:
dirnames.remove(each)
for name in filenames:
file = join(dirpath,name) # 合并成绝对路径
size = getsize(file) # 获取文件大小(单位:byte 字节)
rank_list,removed_size = rank(rank_list=rank_list,size=size,length=int(top_N))
if removed_size:
try:
rank_dic[size] = file
rank_dic.pop(removed_size)
except:
pass
# 按照字典的key 进行排序
for key,value in sorted(rank_dic.items(),key=lambda d:d[0],reverse=True):
print(value, humanble_size(key))
输入命令:
python find_max_size_file.py /d 10