2010-09-25 3 views
2

Я хотел бы написать скрипт, который обходит дерево файлов, вычисляет хэш для каждого файла и вставляет хэш в таблицу SQL вместе с файловым путем, так что я могу затем запросить и поиск идентичных файлов. Какова будет рекомендуемая функция хэша или команда как инструмент для создания хэшей, которые крайне маловероятны для разных файлов? Благодаря Bmysql/file hash question

ответ

0

вы можете использовать md5 хэш или sha1

function process_dir($path) { 

    if ($handle = opendir($path)) { 
     while (false !== ($file = readdir($handle))) { 
     if ($file != "." && $file != "..") { 
      if (is_dir($path . "/" . $file)) { 
       process_dir($path . "/" . $file); 
      } else { 
       //you can change md5 to sh1 
       // you can put that hash into database 
       $hash = md5(file_get_contents($path . "/" . $file)); 
      } 
     } 
     } 
     closedir($handle); 
    } 
} 

, если вы работаете в Windows, изменения слэши к обратной косой черты.

1

Я работаю над этой проблемой слишком долго. Я нахожусь на третьем (и, надеюсь, окончательном) переписывании.

Вообще говоря, я рекомендую SHA1, поскольку он не имеет известных столкновений (в то время как столкновения MD5 can be found in minutes), а SHA1 не является узким местом при работе с жесткими дисками. Если вы одержимы тем, что ваша программа работает быстро в присутствии твердотельного диска, либо идите с MD5, либо дни отхода и дни вашего времени, выясняя, как распараллелить операцию. В любом случае do   не   распараллеливать   хеширование, пока ваша программа не сделает все, что вам нужно.

Кроме того, я рекомендую использовать sqlite3. Когда я делал хэши файлов программных файлов в базе данных PostgreSQL, вставки базы данных были настоящим узким местом. Конечно, я мог бы попробовать использовать COPY (я забыл, если бы я сделал или нет), и я предполагаю, что это было бы достаточно быстро.

Если вы используете sqlite3 и выполняете вставки в блоке BEGIN/COMMIT, вы, вероятно, смотрите около 10000 вставок в секунду при наличии индексов. Однако то, что вы можете сделать с результирующей базой данных, делает все это стоящим. Я сделал это примерно с 750000 файлами (85 ГБ). Вся операция вставки и SHA1 занимает менее часа, и она создала файл sqlite3 размером 140 МБ. Однако мой запрос на поиск дубликатов файлов и сортировку их по идентификатору занимает менее 20 секунд.

Таким образом, используя базу данных хорошо, но обратите внимание на накладные расходы на вставку. SHA1 более безопасен, чем MD5, но потребляет около 2,5x мощности процессора. Тем не менее, I/O имеет тенденцию быть узким местом (процессор занимает второе место), поэтому использование MD5 вместо SHA1 действительно не сэкономит вам много времени.

+0

насколько вы продвигаетесь вместе со своим инструментом? Я искал простой инструмент, который делает это целую вечность, но не может найти что-либо в Интернете за пределами очевидных инструментов «сравнить два каталога». – b20000

+0

Моя программа уже способна загружать данные дерева файлов в базу данных и хешировать файлы; это работает сказочно. В настоящее время я работаю над проблемой замены дубликатов файлов на hardlinks. Обратите внимание, что моя программа, вероятно, будет работать только в Linux и других Unix-подобных системах, потому что она привязана к структуре stat, заполненной ['lstat()') (http://linux.die.net/man/2/lstat). –

+0

Кроме того, он еще не имеет интерфейса; вам нужно будет вставить путь, который вы хотите сканировать, а для более сложных операций - научиться работать с кодом Haskell. –

0

Вот решение, которое я понял. Я не делал все это в PHP, хотя это было бы достаточно легко сделать, если вы хотите:

$fh = popen('find /home/admin -type f | xargs sha1sum', 'r'); 
$files = array(); 
while ($line = fgets($fh)) { 
    list($hash,$file) = explode(' ', trim($line)); 

    $files[$hash][] = $file; 
} 
$dupes = array_filter($files, function($a) { return count($a) > 1; }); 

Я понимаю, что я не использовал базы данных здесь. Сколько файлов вы собираетесь индексировать? Вам нужно помещать эти данные в базу данных, а затем искать там обманов?

+0

спасибо - я написал сценарий тем временем, который использует sqllite DB – b20000