Verimli bir metin dosyasının satır sayısını sayma.

8 Cevap php

Ben sadece benim komut dosyası bana ölümcül bir hata veriyor öğrendim:

Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 440 bytes) in C:\process_txt.php on line 109

Bu çizgi şudur:

$lines = count(file($path)) - 1;

Bu yüzden zorluk memeory içine dosya yükleme ve çizgilerin sayısını sayma yaşıyor, ben bellek sorunları kalmadan yapabilirsiniz daha etkili bir yolu olduğunu düşünüyorum?

Ben 2MB 500MB aralığı için satır sayısını saymak gerekir metin dosyaları. Belki Gig bazen.

Herhangi bir yardım için teşekkür ederiz.

8 Cevap

Belleğe tüm dosya yüklemek değildir çünkü bu, daha az bellek kullanacak:

$file="largefile.txt";
$linecount = 0;
$handle = fopen($file, "r");
while(!feof($handle)){
  $line = fgets($handle);
  $linecount++;
}

fclose($handle);

echo $linecount;

fgets loads a single line into memory (if the second argument $length o bizim istediğimiz şeydir hattı) sonuna ulaşıncaya kadar akışından okumaya devam edecektir atlandı. Eğer duvar zaman yanı sıra bellek kullanımı hakkında bakım eğer bu, hala PHP başka bir şey kullanmak kadar çabuk olması pek mümkün değildir.

Herhangi bir satır özellikle uzun (ne satır sonları olmadan bir dosya 2GB karşılaşırsanız?) Ise bu konuda tek tehlike değildir. Hangi parçalar halinde bunu yılında slurping ve sonu-line karakterler sayım yapsak daha iyi durumda:

$file="largefile.txt";
$linecount = 0;
$handle = fopen($file, "r");
while(!feof($handle)){
  $line = fgets($handle, 4096);
  $linecount = $linecount + substr_count($line, PHP_EOL);
}

fclose($handle);

echo $linecount;

Eğer bir Linux / Unix ana Bu çalıştırıyorsanız, kolay çözüm exec() ya da komutu çalıştırmak için benzer wc -l $path kullanmak olacaktır. Sadece yapmak bunu gibi bir şey olmadığından emin olmak için $path İlk dezenfekte ettik emin "/ bir / yol / dosya; rm-rf /".

Ben tüm dosya döngü gerektirmeyen bulunan bir hızlı yolu yoktur

only on *nix systems, pencereler benzer bir yolu olabilir ...

$file = '/path/to/your.file';

//Get number of lines
$totalLines = intval(exec("wc -l '$file'"));

PHP 5.5 kullanıyorsanız, bir generator kullanabilirsiniz. Bu NOT olsa 5.5 önce PHP herhangi bir sürümünde çalışacak. Php.net Gönderen:

"Jeneratörler Iterator arabirimini uygulayan bir sınıf uygulanması yükü veya karmaşıklığı olmadan basit yineleyicileri uygulamak için kolay bir yol sağlar."

// This function implements a generator to load individual lines of a large file
function getLines($file) {
    $f = fopen($file, 'r');

    // read each line of the file without loading the whole file to memory
    while ($line = fgets($f)) {
        yield $line;
    }
}

// Since generators implement simple iterators, I can quickly count the number
// of lines using the iterator_count() function.
$file = '/path/to/file.txt';
$lineCount = iterator_count(getLines($file)); // the number of lines in the file
private static function lineCount($file) {
    $linecount = 0;
    $handle = fopen($file, "r");
    while(!feof($handle)){
        if (fgets($handle) !== false) {
                $linecount++;
        }
    }
    fclose($handle);
    return  $linecount;     
}

Ben yukarıdaki işlevi biraz düzeltme eklemek istedim ...

i kelime 'test' içeren bir dosya olan bir spesifik bir örnek olarak işlev 2 sonucunda döndü. fgets yanlış veya iade eğer öyleyse ben bir onay eklemek için gerekli :)

eğlenmek :)

Birkaç seçeneğiniz var. İlk Eğer dosya çok büyük alabilirsiniz devlet verilen muhtemelen şeyler yapmak için en iyi yol değildir izin availble belleği arttırmaktır. Diğer yol fgets satır satır dosyayı okumak ve yalnızca mevcut hat herhangi bir anda bellekte tüm herhangi bir hafıza sorunlarına neden olmamalıdır bir sayaç, artırmak için kullanmaktır.

Mükemmel çalışıyor.

<?php
$file1 = "./test.txt";
$lines = file($file1); 
$count = count($lines);
echo($count);
?>