簡體   English   中英

在Web服務器上查找文件名中的最大數字

[英]Find highest number in file names on web server

在我的網絡服務器上,我有一個帶有編號圖像文件的文件夾:

...
296.jpg
297.png
298.gif
...

數字是連續的(1,2,3,...)。 文件名僅包含數字(“12.jpg”,而不是“photo_12.jpg”)。 可能無法按文件名編號的順序創建和存儲文件(即2000.jpg可能早於2.jpg)。

我想找到文件名中的最大數字

我這樣做:

$glob = glob("path/to/dir/*");
$highest = max(preg_replace("|[^0-9]|", "", $glob));
// $highest is now something like 381554

是否有較少的資源重量方法?

首先,您必須決定要保存哪種資源,因為根據它是內存,其他內容的IO操作,會有不同的方法。

到目前為止,您的解決方案在工作速度方面是最優化的,但它非常耗費內存,因為文件夾中可能有很多文件,您將達到內存限制。

我建議你在Redis中緩存 max,例如。 然后在每次上傳新圖像時更新它。 要緩存它,你必須先獲取它。 您可以使用簡單的腳本獲取初始最大值:

$max = 0;
foreach (new DirectoryIterator('.') as $fileInfo) {
    if ($fileInfo->isDot()) continue;

    $current = pathinfo($fileInfo->getFilename())['filename'];
    if (!is_numeric($current)) continue;
    if ($current > $max) $max = $current;
}

或者像vladyslav-savchenko建議的那樣調用外部sort命令。

然后你只需要保持更新的最大值。 通過每次上傳,由兩者的cron更新。

這可能是一種有效的方式

$numeric_files=glob("[0-9]*.*");
$slike = array_map(function($e){return pathinfo($e, PATHINFO_FILENAME);}, $numeric_files);
echo max($slike);

從...開始

$path = "path/to/dir/";

讓我們得到一個文件數組

// $ MYFILE

if ($handle = opendir($path)) {
    while (false !== ($entry = readdir($handle))) {
        if ($entry != "." && $entry != "..") {
            if(!is_dir($entry)){
              $myFile[] = substr($entry,0,strrpos($entry, "."));
            }
        }
    }
    closedir($handle);
}

然后我們可以對數組進行排序

rsort($myFile,SORT_NUMERIC);

第一個將是我們正在搜索的那個

print $myFile[0];

這是一個例子,未經測試。

我認為這不會產生良好的解決方案。 特別是對於大量的文件我正在假設,因為你的評論最高的數字是大約381k。 當您有太多的訪問者和/或緩慢/高負載的服務器時,這將導致高I / O並且可能導致真正的性能問題,可能存在用於存儲圖像的(較舊的)HDD。

我建議你將文件名存儲在數據庫中。 即使你沒有使用數據庫,這也是最好的解決方案,因為你可以通過干凈的SQL查詢得到最高的數字,這將導致更少的I / O負載,而不是掃描文件系統上的巨大的directorys。 此外,您可以從索引中獲益,這些索引將再次優化數據庫查詢的速度。

當你在一個文件夾中存放所有文件時,不需要存儲完整路徑甚至是壞主意。 在這種情況下,當您可能希望稍后編輯路徑時,您將產生不必要的冗余,這將浪費存儲並產生額外的工作。 最好只存儲文件名,並在我們的配置或腳本中為路徑創建一個常量

define('IMAGE_PATH', '/var/www/images');

如果要繼續使用所選圖像,可以執行以下操作:

$fullImagePath = IMAGE_PATH . $databaseQueryResult['fileName'];

我不知道你想做什么,但是當你還沒有使用數據庫時考慮你的設計是個好主意。 圖像托管區域中的某些東西對我來說就像數據庫在這里是一個好主意,也適用於您可能想要實現的其他功能。

你可以使用這樣的東西:

$path = 'path_to_directory';

$command = 'ls ' . escapeshellarg($path) . ' | sort -rn | head -1';

if (!($output = system($command))) {
    print 'Error during execution of: "' . $command . '"';
}

print $output;

以下是我對二進制搜索的評論。

它不需要內存,只需要0.003秒和35個文件檢查,包含100,000個文件。

我想你可以用PHP編寫代碼,或者用shell代替它。

#!/bin/bash
checkfile(){
   if [ -f "$1.jpg" ]; then
      echo DEBUG: Testing ${i}.jpg, exists - so move min marker to $1
      min=$1
      return 0
   else
      echo DEBUG: Testing ${i}.jpg, nope - so move max marker to $1
      max=$1
      return 1
   fi
}
i=1
min=0
max=-1
while : ; do
   if checkfile $i && [[ $max -eq -1 ]]; then
     ((i*=2))
   else
     ((i=(max+min)/2))
   fi
   diff=$((max-min))
   [[ $diff -eq 1 ]] && break
done
echo Result:$min

輸出:

DEBUG: Testing 1.jpg, exists - so move min marker to 1
DEBUG: Testing 2.jpg, exists - so move min marker to 2
DEBUG: Testing 4.jpg, exists - so move min marker to 4
DEBUG: Testing 8.jpg, exists - so move min marker to 8
DEBUG: Testing 16.jpg, exists - so move min marker to 16
DEBUG: Testing 32.jpg, exists - so move min marker to 32
DEBUG: Testing 64.jpg, exists - so move min marker to 64
DEBUG: Testing 128.jpg, exists - so move min marker to 128
DEBUG: Testing 256.jpg, exists - so move min marker to 256
DEBUG: Testing 512.jpg, exists - so move min marker to 512
DEBUG: Testing 1024.jpg, exists - so move min marker to 1024
DEBUG: Testing 2048.jpg, exists - so move min marker to 2048
DEBUG: Testing 4096.jpg, exists - so move min marker to 4096
DEBUG: Testing 8192.jpg, exists - so move min marker to 8192
DEBUG: Testing 16384.jpg, exists - so move min marker to 16384
DEBUG: Testing 32768.jpg, exists - so move min marker to 32768
DEBUG: Testing 65536.jpg, exists - so move min marker to 65536
DEBUG: Testing 131072.jpg, nope - so move max marker to 131072
DEBUG: Testing 98304.jpg, exists - so move min marker to 98304
DEBUG: Testing 114688.jpg, nope - so move max marker to 114688
DEBUG: Testing 106496.jpg, nope - so move max marker to 106496
DEBUG: Testing 102400.jpg, nope - so move max marker to 102400
DEBUG: Testing 100352.jpg, nope - so move max marker to 100352
DEBUG: Testing 99328.jpg, exists - so move min marker to 99328
DEBUG: Testing 99840.jpg, exists - so move min marker to 99840
DEBUG: Testing 100096.jpg, nope - so move max marker to 100096
DEBUG: Testing 99968.jpg, exists - so move min marker to 99968
DEBUG: Testing 100032.jpg, nope - so move max marker to 100032
DEBUG: Testing 100000.jpg, exists - so move min marker to 100000
DEBUG: Testing 100016.jpg, nope - so move max marker to 100016
DEBUG: Testing 100008.jpg, nope - so move max marker to 100008
DEBUG: Testing 100004.jpg, nope - so move max marker to 100004
DEBUG: Testing 100002.jpg, nope - so move max marker to 100002
DEBUG: Testing 100001.jpg, nope - so move max marker to 100001
Result:100000

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM