Очередное обновление Windows раздуло систему на 600 Мб. На диске С: из 100 Гб осталось последних свободных 300 Мб. В папке Downloads больших файлов не осталось, а очистка кешей и временных файлов через программу CCleaner спасает на неделю. Пришла пора глобальной чистки системы. За 2 года Windows оброс кучей ненужных файлов, которые нужно найти и удалить. Размер файла стал основным критерием поиска. Я решил вручную просмотреть все файлы более 50 Мб. Если бы это был Линукс, то хватило бы команды:
find / -type f | xargs du -sh | sort -n | tail -50
Но в Линуксе такой проблемы с местом и не возникло бы. Для Windows существует много готовых утилит, даже расширенного поиска Total Commander хватило бы для данной задачи. Но я решил не искать легких путей и за 30 минут все сделать своими руками на Python.
Код первой версии программы был необычайно прост:
import os
def searchBigFiles(path, bigSize):
folder=os.listdir(path)
if path=='\':
path=''
for element in folder:
if os.path.isfile(path+'\'+element):
statinfo=os.stat(path+'\'+element)
if(statinfo.st_size>1024*1024*bigSize):
size=round(statinfo.st_size/(1024*1024),1)
print(str(size)+' Mb - '+path+'\'+element)
elif os.path.isdir(path+'\'+element):
searchBigFiles(path+'\'+element, bigSize)
searchBigFiles('\xampp', 5)
Программа выводит на экран все файлы более 5 Мб, которые находятся в папке «xxamp». Скрипт сработал без ошибок. Но в корне диска C: он выдал ошибку:
PermissionError: [WinError 5] Отказано в доступе: '\Documents and Settings\*.*'
Запуская файл от имени Администратора, программа оказалась не защищена от таких ошибок:
- PermissionError — ошибка сработала для 89 папок из 85984 просмотренных. Связана она с тем, что часть папок таких как «Documents and Settings» на самом деле не существуют, хотя os.path.isdir для них возвращает True.
- FileNotFoundError — сработала только для файла программы Evernote.
Дописав блок try-catch, получили код, который смог проверить весь диск C: без ошибок:
import os
def searchBigFiles(path, bigSize):
try:
folder=os.listdir(path)
if path=='\':
path=''
for element in folder:
if os.path.isfile(path+'\'+element):
statinfo=os.stat(path+'\'+element)
if(statinfo.st_size>1024*1024*bigSize):
size=round(statinfo.st_size/(1024*1024),1)
print(str(size)+' Mb - '+path+'\'+element)
elif os.path.isdir(path+'\'+element):
searchBigFiles(path+'\'+element, bigSize)
except PermissionError:
print('no access to folder: '+path)
except FileNotFoundError:
print('folder doesn't exist: '+path)
searchBigFiles('\', 100)
Потратив еще 30 мин времени, я сделал тюнинг скрипта: добавил ООП, сортировку по размеру файла, оформил красивый формат вывода данных. Конечный код приведен ниже:
import os
class CleanDiskC:
total=0;
countFiles=0;
countFolders=0;
fileNotFoundError=list()
permissionError=list()
files=list()
def __init__(self, bigSize=50, state=True):
self.bigSize=bigSize
self.stateless=state
def printRow(self, size, path):
size=str(size)+'Mb'
while(len(size)<8):
size+=' '
print('|| '+size+'|| '+path)
def findBigFiles(self, path):
if not self.stateless:
print('Progress: |', end='')
self.searchBigFiles(path)
if not self.stateless:
if len(self.fileNotFoundError)>0:
print('nnCan't find files:')
print('----------------------------')
for elem in self.fileNotFoundError:
print(elem)
print('----------------------------')
print('Total: '+str(len(self.fileNotFoundError))+' elementsn')
if len(self.permissionError)>0:
print('nnDon't have pernission to access folder:')
print('----------------------------')
for elem in self.permissionError:
print(elem)
print('----------------------------')
print('Total: '+str(len(self.permissionError))+' foldersn')
print('nFiles with size more then '+str(self.bigSize)+'Mb:')
print('----------------------------')
self.files.sort(key=lambda x: x['size'], reverse=True)
for elem in self.files:
self.printRow(elem['size'], elem['path'])
print('----------------------------')
print('Total big files store: '+str(round(self.total/1024,1))+'Gb')
print('Total cheched: '+str(self.countFiles)+' files')
print('Total checked: '+str(self.countFolders)+' folders')
def searchBigFiles(self, path):
self.countFolders+=1
try:
folder=os.listdir(path)
if path=='\':
path=''
for element in folder:
if os.path.isfile(path+'\'+element):
self.countFiles+=1
if not self.stateless:
if self.countFiles%10000==0:
print(str(self.countFiles)+'|',end='')
statinfo=os.stat(path+'\'+element)
if(statinfo.st_size>1024*1024*self.bigSize):
size=round(statinfo.st_size/(1024*1024),1)
self.total+=size
if self.stateless:
self.printRow(size, path+'\'+element)
else:
self.files.append({'size':size, 'path':path+'\'+element})
elif os.path.isdir(path+'\'+element):
self.searchBigFiles(path+'\'+element)
except PermissionError:
if self.stateless:
print('no access to folder: '+path)
else:
self.permissionError.append(path)
except FileNotFoundError:
if self.stateless:
print('folder doesn't exist: '+path)
else:
self.fileNotFoundError.append(path)
#bigSize: default=50Mb
#stateless: default=True
do=CleanDiskC(50, False)
do.findBigFiles('\')
Закончив скрипт, я вернулся к первоначальной задаче и занялся диском. В корзину ушло:
- .Trash-1000 — странным образом в корне диска C: оказалась скрытая папка Линукса с фильмом «Джанго освобожденный» — 2,5 Гб
- виртуальная машина VirtualBox со снапшотами — 5 Гб
- бэкапы iPad, iPhone (в настройках iTunes был указан другой диск) — 7 Гб
- затерянные ранее загруженные файлы — 2 Гб
- файлы проектов обработки видео — 10 Гб
Получилось безболезненно освободить 27 Гб. Такой подход позволил подробнее ознакомится с файлами операционной системой Windows и их взаимодействием с языком программирования Python.
Автор: coolweb