Lo más cercano que he visto en el PHP docs, es fread() de una longitud dada, pero que no especifica que la línea de inicio. Cualquier otra sugerencia?

OriginalEl autor lock | 2009-02-05

7 Comentarios

  1. 12

    Usted no va a ser capaz de leer a partir de la línea X, ya que las líneas pueden ser de longitud arbitraria. Así que usted tendrá que leer desde el principio contando el número de líneas de lectura para llegar a la línea de X. Por ejemplo:

    <?php
    $f = fopen('sample.txt', 'r');
    $lineNo = 0;
    $startLine = 3;
    $endLine = 6;
    while ($line = fgets($f)) {
        $lineNo++;
        if ($lineNo >= $startLine) {
            echo $line;
        }
        if ($lineNo == $endLine) {
            break;
        }
    }
    fclose($f);
    O usted podría utilizar el archivo() y array_slice(), como en mi respuesta 🙂
    Sí, excepto que lee todo el archivo. Este código sólo lee el mínimo requerido.
    se que el trabajo, incluso el archivo es tan grande como en el que actualmente se necesita para trabajar es 25MB?
    sí que debería. El ejemplo que me dio sólo tiene una línea en la memoria. Puede almacenar las líneas en una matriz, siempre y cuando no tenga demasiados. Habiendo dicho que 25Mb no es enorme en comparación con algunos de los archivos de registro que he tenido a proceso.
    Si está ejecutando en la memoria, problemas con scripts de larga duración y baja versiones de PHP es mejor evitar los objetos tanto como sea posible, es por eso que prefiero la respuesta de @grom

    OriginalEl autor grom

  2. 33

    Sí, usted puede hacerlo fácilmente con SplFileObject::buscar

    $file = new SplFileObject('filename.txt');
    $file->seek(1000);
    for($i = 0; !$file->eof() && $i < 1000; $i++) {
        echo $file->current(); 
        $file->next();
    }

    Este es un método de la SeekableIterator de la interfaz y que no debe confundirse con fseek.

    Y porque SplFileObject es iterable usted puede hacer que sea aún más fácil con un LimitIterator:

    $file = new SplFileObject('longFile.txt');
    $fileIterator = new LimitIterator($file, 1000, 2000);
    foreach($fileIterator as $line) {
        echo $line, PHP_EOL;
    }

    De nuevo, esto es de base cero, por lo que la línea de 1001 a 2001.

    +1 SPL es muy agradable y se podía utilizar más la publicidad (y documentación)
    Wow, no sabía que uno, muchas gracias!
    Sólo recuerde que el SPL de la aplicación se implementa de la misma manera que la primera propuesta de solución. Va a empezar a leer el archivo desde el primer byte, una línea a la vez, y dejar el puntero del archivo en la línea deseada. No hay manera de deshacerse de ese problema.
    Gracias. Esto funcionó a la perfección!!

    OriginalEl autor Gordon

  3. 3

    Por desgracia, con el fin de ser capaz de leer de la línea x línea y, tendría que ser capaz de detectar los saltos de línea… y usted tendría que escanear todo el archivo. Sin embargo, asumiendo que estás no preguntando acerca de esto por motivos de rendimiento, usted puede obtener líneas de x a y con los siguientes:

    $x = 10; //inclusive start line
    $y = 20; //inclusive end line
    $lines = file('myfile.txt');
    $my_important_lines = array_slice($lines, $x, $y);

    Ver: array_slice

    Debe tener en cuenta que la matriz se inicia con 0 y la numeración de líneas por lo general comienza con 1. Así que no debería ser un $x-1, $y-1 o recordar $x=10 es realmente $x=11.

    OriginalEl autor Factor Mystic

  4. 3

    Aquí está la solución posible 🙂

    <?php
    $f = fopen('sample.txt', 'r');
    $lineNo = 0;
    $startLine = 3;
    $endLine = 6;
    while ($line = fgets($f)) {
        $lineNo++;
        if ($lineNo >= $startLine) {
            echo $line;
        }
        if ($lineNo == $endLine) {
            break;
        }
    }
    fclose($f);
    ?>
    En la solución de todo el archivo es de lectura.
    Pero lee todas las líneas antes de X. La cuestión es preguntar si esta parte puede ser omitido, ¿no?
    Ver el $startLine y $endLine variables, se va a leer sólo las líneas.
    La pregunta no es acerca del procesamiento de sólo líneas dadas (>=startLine && <= endLine). Se trata de minimizar el número de de operación de lectura en el disco.
    Es una buena solución, pero aún requiere mucho tiempo. La más profunda de ir en un archivo más largo será el tiempo… Y tengo la intención de trabajar con los archivos que tienen más de 10,000 líneas.

    OriginalEl autor Sarfraz

  5. 3

    Bueno, usted no puede utilizar la función de el fseek para buscar la posición adecuada debido a que se trabaja con un número determinado de bytes.

    Creo que no es posible sin algún tipo de caché o ir a través de las líneas de una después de la otra.

    ¿Qué acerca de una línea de caché? Almacenar en un lugar donde el byte posiciones de cada línea, a continuación, utilizar el fseek() para llegar a ellos.
    Sería una buena solución.
    studer: Usted está hablando acerca de la Indexación de un archivo? Esto podría ser una solución interesante si el archivo era estático y no cambiaría la mayoría del tiempo. Por desgracia, los archivos que me voy a leer el código fuente de los archivos todavía en desarrollo, por lo que la indexación es fuera de la cuestión.
    Sí, indexación de caché y el índice. (La marca de tiempo en el archivo podría dar una indicación de si la caché de índice es todavía válida). PHP es sorprendentemente rápido para estas tareas, y si usted tiene varias solicitudes para el mismo archivo antes de que se cambia de nuevo, podría ser lo suficientemente rápido como para sacar esto adelante.

    OriginalEl autor Martin Vseticka

  6. 0

    Si usted está buscando para las líneas a continuación, usted no puede utilizar fread debido a que se basa en un desplazamiento de bytes, no el número de saltos de línea. Usted realmente tiene que leer el archivo para encontrar los saltos de línea, por lo que una función diferente es el más apropiado. fgets va a leer el archivo línea por línea. Arrojan que en un bucle y capturar sólo las líneas que desee.

    OriginalEl autor Andrew Vit

  7. 0

    Tenía miedo de que… supongo que es el plan B :S

    Para cada petición AJAX voy a:

    1. Leer en una cadena el número de líneas voy a devolver al cliente.
    2. Copia de la resto del archivo en un archivo temporal.
    3. Cadena devuelta al cliente.

    Es cojo, y probablemente será bastante lenta, con más de 10,000 líneas de los archivos, pero supongo que es mejor que leer lo mismo una y otra vez, al menos, el archivo temporal se acorta con cada solicitud… No?

    OriginalEl autor thedp

Dejar respuesta

Please enter your comment!
Please enter your name here