2011-02-17 24 views
2

第一篇文章,而不是提出一個問題,提出一個我找不到答案的答案,可能會幫助別人。通過增加重複的文件名保護

問題是本地保存文件上傳,並試圖找到一個很好的方式來處理重複的文件名。

鑑於FILENAME.EXT的文件名這樣可以形成,這將給形式filename- \ d + .EXT不存在

$file = "upload.jpg"; 

    while(is_file($file)) 
    { 
     preg_match("/\d+\.[^.]*$/", $file, $matches); 
     if (!$matches) 
     { 
      $file = preg_replace('/(\.[^.]*)$/', '-1${1}', $file); 
      echo $file."<br>"; 
     } 
     else 
     { 
      list($i, $extension) = explode(".",$matches[0]); 

      $file = preg_replace('/(\d+\.[^.]*)$/', ++$i.".".$extension, $file); 
     } 
} 

    echo $file; 

希望的第一個文件名,可能會幫助別人

+3

歡迎,您應該在該位置發佈問題。當別人提問時回答:) – Sarfraz 2011-02-17 18:16:19

回答

3

該算法不可縮放。上傳ñ文件具有相同的名稱將導致O(ñ)在此算法的行爲,導致了O(ñ²)總運行時間,包括O(ñ²)文件系統的訪問。這對服務器應用程序來說並不美妙。由於文件系統的工作方式,它也無法修復。

更好的解決方案:即已經在一個數據庫表中使用

  1. 存儲的文件名,它們映射到它們的使用次數。
  2. 在文件名中放入高粒度時間戳。
  3. 使用內容的SHA1(或MD5)散列作爲文件名。這也可以防止上傳重複文件,如果這很重要。

如有必要,使用數據庫將文件名映射回人類可讀的名稱。

1

最好的解決辦法就是以YYYYDDMMHHMMSS的形式附上時間戳,你不會在整個生活中發生衝突;) 另外它的時間複雜度非常低。 你可以做的另一件事..你可以直接跳過名稱檢查,而不是文件名稱前。 「1.jpg」如果您正在上傳 只需附加1(timestamp).jpg,那麼您甚至不需要遍歷文件系統。希望它有幫助

前。 in PHP

$timestamp=date("YmdGis"); 
it will generate something like 
20111122193631 
;) 
0

我已經做出了自己的解決方案。這裏是:

function recursive_increment_filename ($path, $filename) 
    { 
     $test = "{$path}/{$filename}"; 
     if (!is_file($test)) return $test; 

     $file_info = pathinfo($filename); 
     $part_filename = $file_info['filename']; 

     if (preg_match ('/(.*)_(\d+)$/', $part_filename, $matches)) 
     { 
      $num = (int)$matches[2] +1; 
      $part_filename = $matches[1]; 
     } 
     else 
     { 
      $num = 1; 
     } 
     $filename = $part_filename.'_'.$num; 

     if (array_key_exists('extension', $file_info)) 
     { 
      $filename .= '.'.$file_info['extension']; 
     } 

     return recursive_increment_filename($path, $filename); 
    } 

$url = realpath(dirname(__FILE__)); 

$file = 'test.html'; 
$fn = recursive_increment_filename($url, $file); 

echo $fn;