Dosyasındaki son satırı oku

9 Cevap php

Ben bir sorun haline darbeleme oldum. Birkaç çalışan süreçlerden çıktı yazılı olduğu bir Linux kutusu üzerinde bir günlüğü var. Bu dosya bazen gerçekten büyük alabilirsiniz ve ben o dosyanın son satırı okumak gerekir.

Sorun bu günlük dosya boyutu oldukça sunucu için iyi değil 5-6MB üzerine aldığında bu eylem oldukça sık bir AJAX isteği üzerinden çağırılabilir ve iradesidir. Yani sadece ölüme kutumu yüklemek çünkü ben tüm dosyayı okumak ve onunla geçmesine veya RAM yüklemek için son satırı okumak değil zorunda düşünüyorum.

O Apache düzgün çalıştırmak değil sunucu zarar ya da öldürmek için bu işlem için herhangi bir optimizasyon var mı?

Ben başka bir seçenek exec('tail -n 1 /path/to/log') için ama o kadar iyi gelmiyor.

Daha sonra edit:. I DO NOT want to put the file in RAM because it might get huge. fopen() bir seçenek değildir

9 Cevap

Bu çalışması gerekir:

$line = '';

$f = fopen('data.txt', 'r');
$cursor = -1;

fseek($f, $cursor, SEEK_END);
$char = fgetc($f);

/**
 * Trim trailing newline chars of the file
 */
while ($char === "\n" || $char === "\r") {
    fseek($f, $cursor--, SEEK_END);
    $char = fgetc($f);
}

/**
 * Read until the start of file or first newline char
 */
while ($char !== false && $char !== "\n" && $char !== "\r") {
    /**
     * Prepend the new char
     */
    $line = $char . $line;
    fseek($f, $cursor--, SEEK_END);
    $char = fgetc($f);
}

echo $line;

Kullan fseek. Sen son konuma aramak ve bir "\ n" bulana kadar (kullanım ftell mevcut konumunu anlatmak için) geriye doğru aramak.


$fp = fopen(".....");
fseek($fp, -1, SEEK_END); 
$pos = ftell($fp);
$LastLine = "";
// Loop backword util "\n" is found.
while((($C = fgetc($fp)) != "\n") && ($pos > 0)) {
    $LastLine = $C.$LastLine;
    fseek($fp, $pos--);
}

NOT: Ben test ettik. Bazı ayarlanması gerekebilir.

GÜNCELLEME: Teşekkürler Syntax Error boş dosya hakkında işaret için.

:-D

Update2: $LastLine = "" de noktalı virgül eksik, başka bir sözdizimi hatası Fixxed

Sen fseek fonksiyonu arıyoruz. Orada yorum bölümünde bir dosyanın son satırını okumak için nasıl çalışma örnekleri vardır.

Eğer çizgi uzunluğu üst sınırı bilmek eğer böyle bir şey yapabilirdi.

$maxLength = 1024;
$fp = fopen('somefile.txt', 'r');
fseek($fp, -$maxLength , SEEK_END); 
$fewLines = explode("\n", fgets($fp, $maxLength));
$lastLine = $fewLines[count($fewLines) - 1];

In response to the edit: Sadece dosya için bir tanıtıcı elde fopen (yani emin var olun, süreç .. iznine sahip os bir süreç, vb dosyayı kullanan bildirir). Bu örnekte dosyadan sadece 1024 karakter belleğe okunacaktır.

function readlastline() 
{ 
       $fp = @fopen("/dosmnt/LOGFILE.DAT", "r"); 
       $pos = -1; 
       $t = " "; 
       while ($t != "\n") { 
             fseek($fp, $pos, SEEK_END); 
             $t = fgetc($fp); 
             $pos = $pos - 1; 
       } 
       $t = fgets($fp); 
       fclose($fp); 
       return $t; 
} 

Source: http://forums.devshed.com/php-development-5/php-quick-way-to-read-last-line-156010.html

Would it be possible to optimize this from the other side? If so, just let the logging application always log the line to a file while truncating it (i.e. > instead of >>)

Bazı optimizasyon olsa da, sadece dosyayı açmak ve son satırı nerede olacağını ortalama log hat genişliği ile tahmin edemezdi "tahmin" yoluyla elde edilebilir. Fseek ile bu konuma atlamak ve son satırı bulun.

Senin sorunun this one benziyor

Belleğe tüm dosyayı yüklenmesini önlemek için en iyi yaklaşım gibi görünüyor:

$file = escapeshellarg($file); // for the security concious (should be everyone!)
$line = `tail -n 1 $file`;

http://php.net/manual/en/function.fseek.php yorumlarından denenmemiş kodu

jim at lfchosting dot com 05-Nov-2003 02:03
Here is a function that returns the last line of a file.  This should be quicker than reading the whole file till you get to the last line.  If you want to speed it up a bit, you can set the $pos = some number that is just greater than the line length.  The files I was dealing with were various lengths, so this worked for me. 

<?php 
function readlastline($file) 
{ 
        $fp = @fopen($file, "r"); 
        $pos = -1; 
        $t = " "; 
        while ($t != "\n") { 
              fseek($fp, $pos, SEEK_END); 
              $t = fgetc($fp); 
              $pos = $pos - 1; 
        } 
        $t = fgets($fp); 
        fclose($fp); 
        return $t; 
} 
?>

Ben bir diziye dosyasını okur) (dosyayı kullanmak istiyorsunuz, dizi ters ve ilk öğeyi almak ya da dizi pop:

$ Last_line = array_pop (dosya ($ dosya));

Eğer performans deneyin dosyayı açıp içine gezinmek için dosya tanıtıcısı kullanarak istiyorum.