Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 1, 2017 19:42:33

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

Нужно заархивировать

Доброго времени суток.
Приступил к изучению Пайтона и есть трудности.
В общем есть задача.
Существует директория /root/test/ в ней некое количество файлов размером от 100Кб (примерно) до 28Мб (опять таки примерно). А теперь собственно сама задача: необходимо сортивать эти файлы по директориям и заархивить таким образом, чтобы каждая заархивированная директория не превышала 50 Мб.
Все мои попытки были тщетны, к примеру если наполню директорию до 48 Мб, а следующий файл будет 3Мб, то цикл конечно же остановится, но на 51 Мб в итоге, что выходит за рамки моей задачи.

Офлайн

#2 Фев. 1, 2017 20:37:37

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Нужно заархивировать

Так вы без питона своими словами изложите алгоритм который хотите реализовать.

А вообще архиваторы умеют бить архивы на куски заданного размера, надо просто ключи правильно задать :)



Офлайн

#3 Фев. 2, 2017 02:49:16

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10016
Репутация: +  857  -
Профиль   Отправить e-mail  

Нужно заархивировать

stepan.puzan31
В общем есть задача.
Довольно сложная задача для новичка. Её делать-то надо на shell'е, а на питоне она ещё сложнее, чем на shell'е, делается, так как он для таких действий не очень заточен, в отличие от shell'а.

По крайней мере я бы на питоне это делать не стал, хотя владею и shell'ом, и питоном одинаково, так как на питоне это будет муторнее раза в три. Хотя для тренировки самих навыков в питоне можно и написать, если задачка именно учебная.



Отредактировано py.user.next (Фев. 2, 2017 02:54:22)

Офлайн

#4 Фев. 2, 2017 05:08:10

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

Нужно заархивировать

А вообще архиваторы умеют бить архивы
Каждый архив должен иметь возможность использования без других)


Её делать-то надо на shell'е, а на питоне она ещё сложнее
По Пайтону я хотябы книжку открывал, и некоторые файловые манипуляции на нем уже реализованы. Но вот тут пока не ясо что делать.
Но все равно, спасибо.

Офлайн

#5 Фев. 2, 2017 05:50:54

scidam
Зарегистрирован: 2016-06-15
Сообщения: 288
Репутация: +  35  -
Профиль   Отправить e-mail  

Нужно заархивировать

Алгоритм видится мне следущий:

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] # удаляем тех,  кто в списке не удаление

В результате, получим оптимальный массив контейнеров – каждый из которых не превосходит 50 МБ. Далее, в соответствии с файлами в контейнерах, можно сформировать директории и их упаковать.



Отредактировано scidam (Фев. 2, 2017 05:51:14)

Офлайн

#6 Фев. 2, 2017 05:53:42

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Нужно заархивировать

scidam

Зачем такие многоэтажные конструкции?

     for k in reversed(range(len(files_array))):
          container.append(files_array[k])

Достаточно же просто
 for k in reversed(files_array):
          container.append(k)



Офлайн

#7 Фев. 2, 2017 06:24:17

scidam
Зарегистрирован: 2016-06-15
Сообщения: 288
Репутация: +  35  -
Профиль   Отправить e-mail  

Нужно заархивировать

FishHook
Да, согласен, можно упростить. Тогда и pendings не нужен будет, достаточно будет удалить элементы, которые в текущем контейнере.

Офлайн

#8 Фев. 2, 2017 20:32:23

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

Нужно заархивировать

Большое спасибо за помощь)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version