variable una session_destroy sesion recuperar inicializar ini_set guardar destruir delete php file memory line

una - Cómo guardar memoria al leer un archivo en Php?



recuperar session php (7)

Tengo un archivo de 200 kb, lo que uso en varias páginas, pero en cada página solo necesito 1-2 líneas de ese archivo, así que ¿cómo puedo leer solo estas líneas si necesito el número de línea?

Por ejemplo, si solo necesito la 10ma línea, no quiero cargar en la memoria todas las líneas, solo la 10ma línea.

¡Perdón por mi mal ingles!


¿Cambia el contenido del archivo? Si es estático o relativamente estático, puede crear una lista de compensaciones donde quiera leer sus datos. Por ejemplo, si el archivo cambia una vez al año, pero lo lee cientos de veces al día, puede precomputar las compensaciones de las líneas que desea y saltar directamente a ellas de esta manera:

$offsets = array(); while ($line = fread($filehandle)) { .... find line 10 .... } $offsets[10] = ftell($filehandle); // store line 10''s location .... find next line $offsets[20] = ftell($filehandle);

y así. Después, trivialmente puede saltar a la ubicación de esa línea de esta manera:

$fh = fopen(''file.txt'', ''rb''); fseek($fh, $offsets[20]); // jump to line 20

Pero esto podría ser excesivo. Intente comparar las operaciones: compare el tiempo que lleva realizar una "lectura de 20 líneas" anticuada versus precomputar / saltar.


¿Por qué solo intentas cargar las primeras diez líneas? ¿Sabes que cargar todas esas líneas es, de hecho, un problema?

Si no has medido, entonces no sabes que es un problema. No pierdas tu tiempo optimizando para no tener problemas. Lo más probable es que cualquier cambio en el rendimiento que tenga al no cargar todo el archivo de 200K sea imperceptible, a menos que sepa con certeza que cargar ese archivo es un cuello de botella.


Pruebe SplFileObject

echo memory_get_usage(), PHP_EOL; // 333200 $file = new SplFileObject(''bible.txt''); // 996kb $file->seek(5000); // jump to line 5000 (zero-based) echo $file->current(), PHP_EOL; // output current line echo memory_get_usage(), PHP_EOL; // 342984 vs 3319864 when using file()

Para dar salida a la línea actual, puede usar current() o simplemente echo $file . Sin embargo, me parece más claro usar el método. También puede usar fgets() , pero eso obtendría la siguiente línea.

Por supuesto, solo necesitas las tres líneas medias. He agregado las llamadas memory_get_usage solo para probar que este enfoque casi no consume memoria.


Recórralos sin almacenarlos, p. Ej.

$i = 1; $file = fopen(''file.txt'', ''r''); while (!feof($file)) { $line = fgets($file); // this gets whole line from the file; if ($i == 10) { break; // break on tenth line } $i ++; }

El ejemplo anterior mantendría la memoria solo para la última línea que obtuvo del archivo, por lo que esta es la manera más eficiente de hacerlo.


usa fgets () . 10 veces :-) en este caso no almacenará las 10 líneas en la memoria


A menos que sepa el desplazamiento de la línea, tendrá que leer cada línea hasta ese punto. Puedes descartar las líneas antiguas (que no quieres) al recorrer el archivo con algo como fgets() . (EDITAR: En lugar de fgets() , sugeriría la solución de @Gordon )

Posiblemente una mejor solución sería usar una base de datos, ya que el motor de la base de datos hará el arduo trabajo de almacenar las cadenas y le permitirá (muy eficientemente) obtener cierta "línea" (No sería una línea sino un registro con una ID numérica, sin embargo, equivale a la misma cosa) sin tener que leer los registros anteriores.


<?php $lines = array(1, 2, 10); $handle = @fopen("/tmp/inputfile.txt", "r"); if ($handle) { $i = 0; while (!feof($handle)) { $line = stream_get_line($handle, 1000000, "/n"); if (in_array($i, $lines)) { echo $line; $line = ''''; // Don''t forget to clean the buffer! } if ($i > end($lines)) { break; } $i++; } fclose($handle); } ?>