Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 16, 2021 10:07:33

Arco
Зарегистрирован: 2021-01-13
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Максимально быстро вычислить размер папок

Приветствую. Нужна помощь по вычислению размера папок в т.ч. системных. Я в данный момент пришёл к выводу что win32com.client является максимально подходящим под мою задачу. Но вот такой вопрос:

import win32com.client as com
folderPath = 'C:\\Program Files'
fso = com.Dispatch("Scripting.FileSystemObject")
folder = fso.GetFolder(folderPath)
#folder = fso.GetSpecialFolder(1)
MB = 1024 * 1024.0
print("%.2f MB" % (folder.Size / MB))
На выходе получаю ошибку:
AppData\Local\Programs\Python\Python39\lib \site-packages\win32com\clien
t\dynamic.py", line 500, in __getattr__
ret = self._oleobj_.Invoke(retEntry.dispid,0,invoke_type,1)
pywintypes.com_error: (-2147352567, ‘Ошибка.’, (0, None, None, None, 0, -2146828218), None)
Я нашёл информацию что такая ошибка возникает из-за прав доступа.
Но другие функции, к примеру OS.path вычисляют размер нормально не зависимо от папки, только делают это очень медленно.
Можно ли при помощи win32 узнавать размер папок в том числе и системных?
Или может быть есть какая-нибудь другая библиотека которая позволяет вычислить размер большой папки достаточно быстро?

Офлайн

#2 Янв. 16, 2021 12:14:02

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Максимально быстро вычислить размер папок

Достаточно быстро это насколько ?
вот например

 from os.path import join, getsize
path = 'c:\\program files\\'
size=0
for root, dirs, files in os.walk(path):
    size+=sum(getsize(join(root, name)) for name in files )
MB = 1024 * 1024.0
print(size / MB, 'MB' )
5 гиговую папку за полторы секунды считает, это достаточно быстро или нет?



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Янв. 16, 2021 12:14:23)

Офлайн

#3 Янв. 16, 2021 13:10:31

Arco
Зарегистрирован: 2021-01-13
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Максимально быстро вычислить размер папок

PEHDOM
Достаточно быстро это насколько ?вот например
Спасибо большое за то что откликнулись. Если говорить откровенно, то это не очень быстро.
Для примера, ну конечно если вам не сложно, возьмите папку гиг на 50 и там будет заметна разница. (Ну на моём железе - Hdd 7200 об.мин.)
Хотелось бы всё таки добить win32com.client. Там где в коде у меня закоментированная строка, она отвечает как раз за получение инфы о системных папках, но у меня так тоже не срабатывает с такой же ошибкой. Вот я и не могу понять почему вроде функция есть, а у меня не работает.

Отредактировано Arco (Янв. 16, 2021 14:08:26)

Офлайн

#4 Янв. 16, 2021 14:40:13

Arco
Зарегистрирован: 2021-01-13
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Максимально быстро вычислить размер папок

Если вдруг у кого-нибудь есть модуль для вычислений на C++ который можно подключить к Python, буду рад если поделитесь.

Офлайн

#5 Янв. 17, 2021 16:20:49

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Максимально быстро вычислить размер папок

Arco
Там где в коде у меня закоментированная строка, она отвечает как раз за получение инфы о системных папках, но у меня так тоже не срабатывает с такой же ошибкой. Вот я и не могу понять почему вроде функция есть, а у меня не работает.
оно работает, в том плане что получает обьект, а “разрешение отклонено” оно выдает когда вы пытаетесь получить доступ к свойству Size. Попробуйте вместо Size вывести, например, Name.
Как это обойти, чесно говоря ХЗ. fso.GetFolder это из VBS. Скрипт на вбс ведет себя ровно также.. Судя по обьяснениям на MSDN такая ошибка вылазит если к вас нету права на “list contents” хотябы на один файл/папку внутри.

Arco
Если вдруг у кого-нибудь есть модуль для вычислений на C++ который можно подключить к Python, буду рад если поделитесь.
Ну такое гуглиться за секунду:
https://www.codespeedy.com/how-to-find-the-size-of-a-folder-in-cpp/
компилируете в ДЛЛ и подкюлчаете через ctypes. это совсем просто.
Можно написать свой модуль для пайтона https://docs.python.org/3/extending/extending.html , там чутка посложнее будет.

Arco
если вам не сложно, возьмите папку гиг на 50 и там будет заметна разница. (Ну на моём железе - Hdd 7200 об.мин.)
А вот тут самое интересное:
Взял я папку 600 гиг(в 'd:\\_Games примонтирован терабайтный WD на 7200 обормотов), скормил вот такой скрипт склепаный на коленке :
 import time, os
from pathlib import Path
from os.path import join, getsize
import win32com.client as com
folderPath = 'd:\\_Games\\Games'
MB = 1024 * 1024
s_time = (time.time())
fso = com.Dispatch("Scripting.FileSystemObject")
folder = fso.GetFolder(folderPath)
print('#1, win32com:', int(folder.Size / MB), 'MB', time.time() - s_time)
s_time = (time.time())
root_directory = Path(folderPath)
print('#2, pathlib:', int(sum(f.stat().st_size for f in root_directory.glob('**/*') if f.is_file()) / MB), 'MB', time.time() - s_time)
s_time = (time.time())
size=0
for root, dirs, files in os.walk(folderPath):
    size+=sum(getsize(join(root, name)) for name in files )
print('#3 os.walk:', int(size / MB), 'MB' , time.time() - s_time)
Результат меня удивил(после MB это секунды сколько оно выполнялось):
>>> 
#1, win32com: 626330 MB 184.51770329475403
#2, pathlib: 626330 MB 105.98217296600342
#3 os.walk: 626330 MB 49.874070167541504
>>>
Еще больше меня удивил повторный запуск:
>>> 
#1, win32com: 626330 MB 3.32000470161438
#2, pathlib: 626330 MB 87.87312316894531
#3 os.walk: 626330 MB 49.45407009124756
>>>
После перезагрузки компа, результат примерно тот же самый.Первый раз GetFolder считает ну очень долго, а последующие почти мгновенно.
Что там внутри GetFolder ХЗ. Скорее всего гдето оно кеширует размеры папок, а потом просто смотрит если папка не менялась то берет значения из кеша, если менялась- пересчитывает. А может еще чтото.
Конечно же для, чистоты экспериемнат нужно было бы после вычисления каждым методом перезапускать ПК, чтото мне подсказывает что результаты #2 и #3 будут в несколько раз большими в случае “холодного запуска”, но тут уже сами можете провести замеры.
Так что смотрите можете реализовать схожий алгоритм на пайтоне, и будет вам “прирост скорости”.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Янв. 17, 2021 21:59:04)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version