fgets()
Sin embargo, usar un bucle de llamadas es una buena solución y la más sencilla de escribir:
aunque internamente el archivo se lee usando un búfer de 8192 bytes, su código aún tiene que llamar a esa función para cada línea.
Es técnicamente posible que una sola línea sea más grande que la memoria disponible si está leyendo un archivo binario.
Este código lee un archivo en fragmentos de 8kB cada uno y luego cuenta el número de líneas nuevas dentro de ese fragmento.
function getLines($file)
{
$f = fopen($file, 'rb');
$lines = 0;
while (!feof($f)) {
$lines += substr_count(fread($f, 8192), "\n");
}
fclose($f);
return $lines;
}
Si la longitud promedio de cada línea es como máximo de 4kB, ya comenzará a ahorrar en llamadas a funciones, y esas pueden sumarse cuando procese archivos grandes.
Punto de referencia
Ejecuté una prueba con un archivo de 1GB; aquí están los resultados:
+-------------+------------------+---------+
| This answer | Dominic's answer | wc -l |
+------------+-------------+------------------+---------+
| Lines | 3550388 | 3550389 | 3550388 |
+------------+-------------+------------------+---------+
| Runtime | 1.055 | 4.297 | 0.587 |
+------------+-------------+------------------+---------+
El tiempo se mide en segundos en tiempo real, vea aquí lo que significa real
\n
) siendo analizado en una máquina con Windows (PHP_EOL == '\r\n'
)