¿Cómo leer un archivo grande línea por línea?
Quiero leer un archivo línea por línea, pero sin cargarlo por completo en la memoria.
Mi archivo es demasiado grande para abrirlo en la memoria y, si intento hacerlo, siempre obtengo errores de falta de memoria.
El tamaño del archivo es de 1 GB.
Puede utilizar la fgets()
función para leer el archivo línea por línea:
$handle = fopen("inputfile.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// process the line read.
}
fclose($handle);
}
if ($file = fopen("file.txt", "r")) {
while(!feof($file)) {
$line = fgets($file);
# do same stuff with the $line
}
fclose($file);
}
Puede utilizar una clase de interfaz orientada a objetos para un archivo: SplFileObject http://php.net/manual/en/splfileobject.fgets.php (PHP 5 >= 5.1.0)
<?php
$file = new SplFileObject("file.txt");
// Loop until we reach the end of the file.
while (!$file->eof()) {
// Echo one line from the file.
echo $file->fgets();
}
// Unset the file to call __destruct(), closing the file handle.
$file = null;
Si desea utilizar foreach
en lugar de while
al abrir un archivo grande, probablemente desee encapsular el while
bucle dentro de un Generador para evitar cargar todo el archivo en la memoria:
/**
* @return Generator
*/
$fileData = function() {
$file = fopen(__DIR__ . '/file.txt', 'r');
if (!$file) {
return; // die() is a bad practice, better to use return
}
while (($line = fgets($file)) !== false) {
yield $line;
}
fclose($file);
};
Úselo así:
foreach ($fileData() as $line) {
// $line contains current line
}
De esta manera puede procesar líneas de archivos individuales dentro de foreach().
Nota: Los generadores requieren >= PHP 5.5
Hay una file()
función que devuelve una matriz de las líneas contenidas en el archivo.
foreach(file('myfile.txt') as $line) {
echo $line. "\n";
}