Форум сайта python.su
0
Доброго времени суток.
Приступил к изучению Пайтона и есть трудности.
В общем есть задача.
Существует директория /root/test/ в ней некое количество файлов размером от 100Кб (примерно) до 28Мб (опять таки примерно). А теперь собственно сама задача: необходимо сортивать эти файлы по директориям и заархивить таким образом, чтобы каждая заархивированная директория не превышала 50 Мб.
Все мои попытки были тщетны, к примеру если наполню директорию до 48 Мб, а следующий файл будет 3Мб, то цикл конечно же остановится, но на 51 Мб в итоге, что выходит за рамки моей задачи.
Офлайн
253
Так вы без питона своими словами изложите алгоритм который хотите реализовать.
А вообще архиваторы умеют бить архивы на куски заданного размера, надо просто ключи правильно задать :)
Офлайн
857
stepan.puzan31Довольно сложная задача для новичка. Её делать-то надо на shell'е, а на питоне она ещё сложнее, чем на shell'е, делается, так как он для таких действий не очень заточен, в отличие от shell'а.
В общем есть задача.
Отредактировано py.user.next (Фев. 2, 2017 02:54:22)
Офлайн
0
А вообще архиваторы умеют бить архивыКаждый архив должен иметь возможность использования без других)
Её делать-то надо на shell'е, а на питоне она ещё сложнееПо Пайтону я хотябы книжку открывал, и некоторые файловые манипуляции на нем уже реализованы. Но вот тут пока не ясо что делать.
Офлайн
35
Алгоритм видится мне следущий:
0. Исходим из предположения, что размер архива данной папки не превосходит ее исходного размера (т.е. архивация не увеличивает занимаемого объема)
1. Создаем массив кортежей т.е. пути к файлам и размеры файлов соответственно (это можно сделать при помощи os модуля)
2. сортируем данный массив по размеру файлов, допустим по возрастанию (как-нибудь так: x=sorted(x, key=lambda x: x))
3. дальше создаем цикл типа while пока текущий массив кортежей непуст, а внутри него другой цикл, который последовательно от большего к меньшему пробует добавить каждый файл, пока размер контейнера меньше 50 МБ:
files_array= [('path/to/file', file_size), ....] # sort it first... containers = [] while files_array: container = [] pendings = [] for k in reversed(range(len(files_array))): container.append(files_array[k]) pendings.append(k) if sum(map(lambda x: x[1], container)) >= 50: container.pop() pendings.pop() containers.append(container) for i in pendings: del files_array[i] # удаляем тех, кто в списке не удаление
Отредактировано scidam (Фев. 2, 2017 05:51:14)
Офлайн
568
scidam
Зачем такие многоэтажные конструкции?
for k in reversed(range(len(files_array))): container.append(files_array[k])
for k in reversed(files_array): container.append(k)
Офлайн
35
FishHook
Да, согласен, можно упростить. Тогда и pendings не нужен будет, достаточно будет удалить элементы, которые в текущем контейнере.
Офлайн
0
Большое спасибо за помощь)
Офлайн