Bir fgets()
çağrı döngüsü kullanmak iyi bir çözümdür ve yazmak için en basit yöntemdir, ancak:
dosya dahili olarak 8192 baytlık bir arabellek kullanılarak okunsa bile, kodunuzun yine de her satır için bu işlevi çağırması gerekir.
İkili bir dosya okuyorsanız, teknik olarak tek bir satırın mevcut bellekten daha büyük olması mümkündür.
Bu kod, her biri 8kB'lik parçalar halinde bir dosyayı okur ve ardından bu öbek içindeki satırsonu sayısını sayar.
function getLines($file)
{
$f = fopen($file, 'rb');
$lines = 0;
while (!feof($f)) {
$lines += substr_count(fread($f, 8192), "\n");
}
fclose($f);
return $lines;
}
Her bir hattın ortalama uzunluğu en fazla 4kB ise, zaten işlev çağrılarından tasarruf etmeye başlayacaksınız ve bunlar büyük dosyaları işlediğinizde toplanabilir.
Kıyaslama
1GB dosya ile bir test yaptım; sonuçlar burada:
+-------------+------------------+---------+
| This answer | Dominic's answer | wc -l |
+------------+-------------+------------------+---------+
| Lines | 3550388 | 3550389 | 3550388 |
+------------+-------------+------------------+---------+
| Runtime | 1.055 | 4.297 | 0.587 |
+------------+-------------+------------------+---------+
Zaman, gerçek zamanlı olarak saniye cinsinden ölçülür, burada gerçek ne anlama geldiğini görün
\n
bir Windows makinesinde (PHP_EOL == '\r\n'
) ayrıştırılan unix tarzı bir dosyanız olabilir ( )