Глава 29. Поиск одинаковых файлов

Постановка задачи
Идеи реализации
Наивная группировка
Хеширование и гнездование
Разработка
Готовая программа

Эта задача посвящена поиску одинаковых файлов среди указанных в командной строке (если указана директория, подразумевается список всех файлов, которые содержатся в ней и во всех её поддиректориях на всю глубину их вложенности).

Результаты работы подобной программы (нашу программу мы назовём finddups.pl) могут быть использованы, например, для удаления ненужных копий имеющихся файлов.

Программа будет выводить имена одинаковых файлов группами, по одному имени в строке, отделяя группы друг от друга пустой строкой. Перед каждой группой выводится размер файлов в группе (естественно, все файлы в группе одного размера). Группы выводятся в порядке возрастания размера файлов. Внутри каждой группы имена файлов лексикографически упорядочены. Выводятся только группы, содержащие более одного файла.

Если в командной строке не перечислены файлы или директории, программа работает с текущей директорией.

Приводим пример вывода нашей будущей программы:

% ./finddups.pl /arch/Mandriva * Размер: 29 /arch/Mandriva/2008.0/i586/install/extra/advertising/02IM_MIGRATION.pl /arch/Mandriva/2010.0/i586/install/extra/advertising/02IM_MIGRATION.pl * Размер: 30 /arch/Mandriva/2008.0/i586/install/extra/advertising/04IM_NETWORK.pl /arch/Mandriva/2010.0/i586/install/extra/advertising/04IM_NETWORK.pl * Размер: 30 /arch/Mandriva/2008.0/i586/install/extra/advertising/01IM_RANGE-a.pl /arch/Mandriva/2010.0/i586/install/extra/advertising/01IM_RANGE-a.pl * Размер: 31 /arch/Mandriva/2008.0/i586/install/extra/advertising/03IM_ONE.pl /arch/Mandriva/2010.0/i586/install/extra/advertising/03IM_ONE.pl * Размер: 35 /arch/Mandriva/2008.0/i586/install/extra/advertising/05IM_PWP.pl /arch/Mandriva/2010.0/i586/install/extra/advertising/05IM_PWP.pl * Размер: 37 /arch/Mandriva/2010.0/i586/doc/images/.svn/prop-base/BDO-GALAXY-BAS.png.svn-base /arch/Mandriva/2010.0/i586/doc/images/.svn/prop-base/BDO-GALAXY.png.svn-base /arch/Mandriva/2010.0/i586/doc/images/.svn/prop-base/warning.png.svn-base * Размер: 44 /arch/Mandriva/2008.0/i586/install/extra/advertising/06IM_FLASH.pl /arch/Mandriva/2010.0/i586/install/extra/advertising/06IM_FLASH.pl * Размер: 54 /arch/Mandriva/2010.0/i586/install/extra/advertising/IM_one.pl /arch/Mandriva/2010.0/i586/install/extra/advertising/IM_one08S.pl /arch/Mandriva/2010.0/i586/install/extra/advertising/IM_one09.pl * Размер: 59 /arch/Mandriva/2010.0/i586/install/extra/advertising/IM_pwp.pl /arch/Mandriva/2010.0/i586/install/extra/advertising/IM_pwp08S.pl /arch/Mandriva/2010.0/i586/install/extra/advertising/IM_pwp09.pl * Размер: 60 /arch/Mandriva/2008.0/i586/media/main/reconfig.urpmi /arch/Mandriva/2010.0/i586/media/main/reconfig.urpmi * Размер: 17858669 /arch/Mandriva/2010.0/i586/media/main/testing/media_info/20100529-042535-hdlist.cz /arch/Mandriva/2010.0/i586/media/main/testing/media_info/hdlist.cz /arch/Mandriva/2010.0/i586/media/media_info/hdlist_main_testing.cz * Размер: 18711170 /arch/Mandriva/2008.0/i586/media/main/updates/media_info/20100218-160509-hdlist.cz /arch/Mandriva/2008.0/i586/media/main/updates/media_info/hdlist.cz /arch/Mandriva/2008.0/i586/media/media_info/hdlist_main_updates.cz * Размер: 18834524 /arch/Mandriva/2008.0/i586/media/contrib/updates/media_info/20090226-183914-hdlist.cz /arch/Mandriva/2008.0/i586/media/contrib/updates/media_info/hdlist.cz /arch/Mandriva/2008.0/i586/media/media_info/hdlist_contrib_updates.cz * Размер: 27151075 /arch/Mandriva/2010.0/i586/media/main/updates/media_info/20100527-155305-hdlist.cz /arch/Mandriva/2010.0/i586/media/main/updates/media_info/hdlist.cz /arch/Mandriva/2010.0/i586/media/media_info/hdlist_main_updates.cz * Размер: 33814299 /arch/Mandriva/2010.0/i586/media/contrib/updates/media_info/20100527-152612-hdlist.cz /arch/Mandriva/2010.0/i586/media/contrib/updates/media_info/hdlist.cz /arch/Mandriva/2010.0/i586/media/media_info/hdlist_contrib_updates.cz * Размер: 36091866 /arch/Mandriva/2008.0/i586/media/main/release/media_info/hdlist.cz /arch/Mandriva/2008.0/i586/media/media_info/hdlist_main.cz * Размер: 47950550 /arch/Mandriva/2010.0/i586/media/main/release/media_info/20100127-150546-hdlist.cz /arch/Mandriva/2010.0/i586/media/main/release/media_info/hdlist.cz /arch/Mandriva/2010.0/i586/media/media_info/hdlist_main.cz * Размер: 58165570 /arch/Mandriva/2008.0/i586/media/contrib/release/hdlist.cz /arch/Mandriva/2008.0/i586/media/contrib/release/media_info/hdlist.cz /arch/Mandriva/2008.0/i586/media/media_info/hdlist_contrib.cz * Размер: 69011132 /arch/Mandriva/2010.0/i586/media/contrib/release/media_info/20100104-105605-hdlist.cz /arch/Mandriva/2010.0/i586/media/contrib/release/media_info/hdlist.cz /arch/Mandriva/2010.0/i586/media/media_info/hdlist_contrib.cz

(здесь некоторые строки вывода пропущены для краткости).

[Примечание]Примечание

К выводу нашей программы следует отнестись с большой осторожностью, если вы намерены удалять за ненадобностью одинаковые файлы. В приведённом примере исследовалась директория /arch/Mandriva, в которой находятся две поддиректории: 2008.0 и 2010.0. Каждая из них содержит дистрибутив Mandriva Linux — соответственно старую и новую версии. Нет ничего удивительного в том, что некоторые файлы в разных версиях дистрибутива оказались одинаковыми. Удаление одной из копий безусловно сэкономит место на диске, но нарушит целостность дистрибутива. Замена одной из копий на символическую ссылку на другой экземпляр сэкономит место, но тогда один из дистрибутивов не сможет жить без другого. При переносе его директории на другое место, или при удалении файлов, на которые указывают ссылки, такие ссылки могут осиротеть. Кроме того, даже в пределах одного дистрибутива программа находит довольно крупные одинаковые файлы, например, /arch/Mandriva/2010.0/i586/media/contrib/release/media_info/20100104-105605-hdlist.cz и /arch/Mandriva/2010.0/i586/media/contrib/release/media_info/hdlist.cz (см. последнюю группу). Но первый из этих файлов уже является символической ссылкой на второй и реально занимает на диске только 9 байт.

Пустые файлы, которые, конечно, все одинаковы, могут показаться хорошими кандидатами для удаления. Однако сам факт их наличия, а также их имена могут нести в себе полезную информацию. Некоторые программы, например, сетевые серверы, единолично обслуживают определённые ресурсы компьютера (скажем, веб-сервер прослушивает сетевой порт № 80). Поэтому недопустима одновременная работа нескольких экземпляров веб-сервера, поскольку эти экземпляры не смогут поделить между собой такой ресурс. Для разрешения этой проблемы (для запрета одновременной работы нескольких экземпляров программы) обычно используют следующий приём: программа, будучи запущена впервые, создаёт в известной директории пустой лок-файл (lock — замок). А, обнаружив лок-файл, программа отказывается продолжать работу, сообщая о том, что один её экземпляр уже работает. По окончании работы лок-файл удаляется. Лок-файлы не всегда создаются пустыми. Часто в них записывается полезная информация о работающей программе, скажем, номер её процесса (PID).

Несмотря на замечания наша программа может подсказать, на какие файлы стоит обратить внимание при «зачистке» диска от ненужных копий.

Информатика-54© А. Н. Швец