| Объединение данных |
|
Как быть, когда необходимо не просто сравнить файлы с данными, но еще и объединить два дерева каталогов в одно? Главная проблема состоит в том, чтобы объединить содержимое одного дерева с другим без создания дубликатов файлов. Вы могли бы просто вслепую скопировать файлы из одного каталога в дPyroй и затем удалить дубликаты файлов, но гораздо эффективнее было бы вообще не создавать дубликаты. Достаточно простое решение этой проблемы состоит в том, чтобы сравнить два каталога с помощью функции dircmp() из модуля filecmp и затем скопировать уникальные файлы с помощью приема, основанного на использовании os.llstdir, описанного выше. Наилучшее решение заключается в использовании контрольных сумм MD5, о чем рассказывается в следующем разделе. Сравнение контрольных сумм MD 5 Вычисление контрольной суммы MD5 файла и сравнение ее с контрольной суммой другого файла напоминает стрельбу из гранатомета по движущейся мишени. Такое мощное оружие вводится в действие, когда требуется полная уверенность в своих действиях, хотя 100-процентную гарантию может дать только побайтовое сравнение файлов. В примере 6.7 показана функция, которая принимает путь к файлу и возвращает его контрольную сумму. Пример 6.7. Вычисление контрольной суммы MD5 файла
Ниже приводится пример использования этой функции в интерактивной оболочке IPython для сравнения двух файлов:
В этом примере контрольные суммы файлов сравниваются вручную, но мы вполне можем использовать программный код, написанный ранее, который возвращает список путей, для рекурсивного сравнивания дерева каталогов и получить список дубликатов. Прелесть удобного API состоит в том, что его теперь можно использовать в оболочке IPython с целью тестирования наших решений в интерактивном режиме. Затем, если решение работает, мы можем создать другой модуль. В примере 6.8 приводится программный код, который отыскивает дубликаты файлов. Пример 6.8. Вычисление контрольных сумм MD5 в дереве каталогов с целью поиска дубликатов файлов
Фрагмент программного кода, который еще не встречался нам в предыдущих примерах, начинается в строке [7]. Здесь мы создали пустой словарь, и затем сохраняем вычисленные контрольные суммы в виде ключей. Благодаря этому легко можно определить, была ли ранее вычислена та или иная контрольная сумма. Если была, мы помещаем файл в список дубликатов. Теперь давайте выделим часть программного кода, которую позднее мы сможем использовать в разных сценариях. В конце концов, это очень удобно. Как это сделать, показано в примере 6.9.
Запустив этот сценарий, мы получили следующий результат:
Пример 6.9. Поиск дубликатов Мы надеемся, вы заметили, что этот пример демонстрирует преимущества повторного использования существующего программного кода. Теперь у нас имеется универсальный модуль, получающий путь к дереву каталогов и возвращающий список дубликатов файлов. Это уже само по себе удобно, но мы можем пойти еще дальше и автоматически удалить дубликаты. Удаление файлов в языке выполняется очень просто - с помощью метода os.remove(). Для этого примера у нас имеется множество файлов размером 10 Мбайт в нашем каталоге /imp. Попробуем удалить один из них, воспользовавшись методом os.remove():
Обратите внимание, как функция дополнения по клавише табуляции в оболочке IPython позволяет увидеть список соответствующих файлов. Вы должны знать, что метод os.remove() удаляет файлы, ничего не сообщая и навсегда, что может не всегда соответствовать нашим желаниям. Учитывая это обстоятельство, мы можем реализовать простой метод, который будет удалять дубликаты, и затем расширить его. Поскольку интерактивная оболочка IPython позволяет легко проверить эту идею, мы напишем проверочную функцию прямо в ней и сразу же проверим ее:
В этом примере мы несколько усложнили свой метод удаления, добавив в него инструкцию print, которая выводит имена удаляемых файлов. Мы уже создали достаточно много программного кода, пригодного для многократного использования, поэтому у нас нет никаких причин останавливаться на достигнутом. Мы можем создать еще один модуль, который будет выполнять различные операции удаления, получая объект типа file. Этот модуль даже не требуется привязывать к поиску дубликатов, его можно использовать для удаления любых файлов. Исходный текст модуля приводится в примере 6.10. Пример 6.10. Модуль delete
В этом модуле имеется три различных метода удаления. Метод удаления в интерактивном режиме запрашивает у пользователя подтверждение для каждого файла, который предполагается удалить. Это может показаться раздражающим, но этот метод обеспечивает хорошую защиту для тех, кто впоследствии будет сопровождать или изменять этот программный код. Метод пробного режима всего лишь имитирует удаление. И, наконец, имеется метод, который удаляет файлы безвозвратно. В конце модуля можно увидеть закомментированные варианты использования каждого из трех методов. Ниже приводятся примеры каждого из методов в действии: • Пробный режим
• Интерактивный режим
• Удаление
Вы можете согласиться, что приемы инкапсуляции, подобные тем, что были продемонстрированы выше, очень удобны, когда приходится иметь дело с данными, потому что вы можете предотвратить возникновение проблем в будущем, абстрагировавшись от конкретной ситуации и решая универсальную задачу. В данном случае нам необходимо было реализовать удаление дубликатов файлов, поэтому был создан модуль, который универсальным способом отыскивает файлы и удаляет их. Мы могли бы создать еще один инструмент, который получает объект типа file и выполняет сжатие файла. И мы действительно вскоре подойдем к этому примеру.
Related Articles
Set as favorite
Bookmark
Email This
Hits: 295 Комментарии (0)RSS feed CommentsНаписать комментарий |