2011-05-04

PHP : 10MB 이상의 파일중에서 중복된 파일 찾기

PHP가 처음에는 웹프로그래밍을 위해서 만들어졌지만, 지금은 CLI 를 지원함으로써, 일반 General Language 로써의 면모도 갖추고 있다. 그러므로, 시스템 관리/일반 어플리케이션 개발 등에도 널리 활용할 수 있다. 필자는 서버 관리를 주로 하고 있으므로, 시스템 관리를 위한 스크립트를 가끔 작성해야 하는데, 이번에는 PHP로 해보았다. 파일서버 관리를 위해서 주기적으로 오래되거나 필요없는 파일들을 삭제해주어야 하는데, 이 중에서도 중복되는 파일을 제거해주는 것이 꽤 효과적이다. 내가 지울수 있는 권한은 없으니, 중복파일 목록을 사용자들에게 주고 직접 지우도록 하면 그나마 쬐끔 용량을 확보하는데 도움이 된다.

아래는 10MB 넘는 파일중에서 중복된 파일을 찾아서 파일에 결과물을 남기도록 하였다. 기존에 Perl, Python, Ruby 등으로 만들어 놓긴 했지만, PHP로 만들어보니 꽤 훌륭하게 동작한다. ^^ 코드는 그다지 최적화된 것 같지는 않지만, 참고는 할 만 할 것이다.


// -----------------------------------------
// 10MB 이상의 파일중에서 중복된 파일 찾기
// -----------------------------------------
$limit_size  = 10000000; // 10MB
$dst_dir     = "M:\\";
$file_list   = array();
$result_list = array();
// -----------------------------------------
 
$start_time = date("Y/m/d H:i:s", time());
 
$i = 0;
$rdi = new RecursiveDirectoryIterator($dst_dir);
try {
    foreach (new RecursiveIteratorIterator($rdi, 
                                            RecursiveIteratorIterator::LEAVES_ONLY, 
                                            RecursiveIteratorIterator::CATCH_GET_CHILD) as $path) {
        if ($path->isFile() && $path->getSize() > $limit_size) {
            $md5sum = md5_file($path->__toString());
            echo "($i) [$md5sum] : ".$path->__toString()."\n";
            $file_list[$i++] = $md5sum."\t".$path->__toString();
        }
 
    }
} catch(Exception $e) {
    echo "Message: ".$e->getMessage();
}
 
 
foreach($file_list as $key => $value) {
    list($md5, $path) = split("\t", $value, 2);
    if(!isset($result_list[$md5])) { $result_list[$md5] = 0; }
    $result_list[$md5] += 1;
}
 
 
$i = 0;
$fh = fopen("result_samefiles_".date("Ymd").".txt", "w") or die("Can't open file");
foreach($result_list as $key => $value) {
    if($value < 2) { continue; }
 
    // fputs ($fh, "\n[$key]\n");
    fputs ($fh, "\n[$i]\n");
    ++$i;
    foreach($file_list as $idx => $file) {
        list($md5, $path) = split("\t", $file, 2);
        if($md5 == $key) {
            fputs ($fh, "$path\n");
        }
    }
}
fclose($fh);
 
 
$end_time = date("Y/m/d H:i:s", time());
 
echo "\nStart Time -> $start_time \n";
echo "End Time   -> $end_time \n\n";

댓글 없음:

댓글 쓰기