kostenloser Webspace werbefrei: lima-city


Zeilen in Datei zählen ?

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    spdata

    spdata hat kostenlosen Webspace.

    Hallo

    ich möchte so Performance-schonend wie möglich die Zeilen einer Datei zählen.

    bekannt ist mir mit file() alle Zeilen als Array einzulesen
    und dann mit count() dieses Array zu zählen

    function count_filerows ($datei) { 
       $fdata = file($datei); 
       $rows = count($fdata); 
    return $rows; 
    }


    Aber mit file() muss ich ja jedesmal die komplette Datei einlesen

    ... gibt es nicht eine Funktion, um je Zeile nur 1 Zeichen einzulesen ?!?
    oder was ganz anderes, um die Zeilen-Anzahl zu ermitteln ?!


    cool wäre halt einfach ein Parameter in file(), der die Länge (Anzahl Zeichen) je Zeile angibt
    ... gibts aber bei file() wohl nicht, siehe: http://php.net/manual/de/function.file.php

    wie kann ich sonst die Anzahl der Zeilen einer Datei möglichst Ressourcen-schonend zählen ?!
    Danke!

    EDIT habe zwei Versuche gemacht mit feof() und fgets() leider ohne Erfolg:


    bei feof() bekomme ich: Fatal error: Maximum execution time of 20 seconds exceeded

    function count_filerows ($datei) { 
    $handle = fopen($datei,'r');
    $rows=0; 
    while(!feof($handle)) { 
       $rows++; 
       }
    fclose($handle);
    return $rows; 
    }




    bei fgets() bekomme ich als Ergebnis immer 0 (null)

    function count_filerows ($datei) { 
    $handle = fopen($datei,'r');
    $rows=0; 
    while ( fgets($handle, 1) !== false ) { 
       $rows++; 
       }
    fclose($handle);
    return $rows; 
    }


    .... die Idee ist denke ich schon gut,
    ??? ... aber warum klappt es nicht ?!? ... wo ist der Fehler?

    Danke!


    Beitrag zuletzt geändert: 19.1.2012 20:31:02 von spdata
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. hackyourlife

    Moderator Kostenloser Webspace von hackyourlife

    hackyourlife hat kostenlosen Webspace.

    spdata schrieb:
    function count_filerows ($datei) { 
    $handle = fopen($datei,'r');
    $rows=0; 
    while(!feof($handle)) { 
       $rows++; 
       }
    fclose($handle);
    return $rows; 
    }
    Fehler: du prüfst nur ob du schon am Dateiende bist, liest aber in der Zwischenzeit kein Zeichen. Deshalb verändert sich der Dateizeiger nicht und die Schleife läuft wie
    while(true) {
        $rows++;
    }


    spdata schrieb:
    function count_filerows ($datei) { 
    $handle = fopen($datei,'r');
    $rows=0; 
    while ( fgets($handle, 1) !== false ) { 
       $rows++; 
       }
    fclose($handle);
    return $rows; 
    }
    Hier liest du immer nur EIN Zeichen (und keine vollständige Zeile).

    Das Einfachste ist wahrscheinlich Folgendes:
    $lines = count(file($datei));

    Du machst ja auch nichts anderes als alle Zeilen lesen ;-)
    Eine andere Möglichkeit gibt es eigentlich auch nicht, da man ja in der Datei nach Zeilenumbrüchen suchen muss und deshalb die gesamte Datei lesen muss.
  4. Autor dieses Themas

    spdata

    spdata hat kostenlosen Webspace.

    hackyourlife schrieb:
    Eine andere Möglichkeit gibt es eigentlich auch nicht, da man ja in der Datei nach Zeilenumbrüchen suchen muss und deshalb die gesamte Datei lesen muss.

    stimmt auch wieder

    schade, dass man mit fgets() auch bis zum Zeilenende auslesen muss,
    ich dachte fgets() macht immer Zeilenweise, und man könnte da nur das erste Zeichen auslesen
    und je Durchlauf der while-Schleife springt fgets() immer eine Zeile weiter
    ... aber das geht ja leider so nicht ... falch gedacht :(

    mit meiner feof() hatte ich dann wohl einen endlos-Zähler ... ^O^

    wenn ich fgets($handle) ohne Angabe von Zeichen (int $length) mache,
    dann geht es ja bis zum Zeilenende (laut php.net Doku)

    also so funktioniert es jetzt bei mir mit fgets()

    function count_filerows ($file) { 
    $handle = fopen($file,'r');
    $i=0; 
       while ( fgets($handle) !== false ) { 
       $i++; 
       }
    fclose($handle);
    return $i; 
    }


    ist nur noch die Frage, was weniger Ressourcen braucht,
    das mit fgets() oder das mit file()

    hackyourlife schrieb:
    Das Einfachste ist wahrscheinlich Folgendes:
    $lines = count(file($datei));

    Du machst ja auch nichts anderes als alle Zeilen lesen ;-)

    stimmt, so ist es einfach, aber auch Ressourcen-sparsamer als mit fgets() ?
    ... die zu prüfende Datei kann zwischen 2 und 10000 Zeilen haben

    da ich es als Funktios-Aufruf will, hier nochmal die Variante mit file()

    function count_filerows ($datei) { 
       $fdata = file($datei); 
       $rows = count($fdata); 
       unset($fdata); 
    return $rows; 
    }


    macht das unset($fdata); hier übergaupt Sinn? ... ist ja innerhalb der Funktion
    und sollte doch nach return sowieso nicht mehr existieren ?!?! oder?


    bzw in Kurzform:

    function count_filerows ($datei) { 
       return count(file($datei)); 
    }



    also was frisst jetzt Euerer Meinung nach weniger Ressourcen ?!

    PS:
    ... wie könnte man das evtl. testen, was schneller ist bzw. weniger RAM / CPU braucht?


  5. spdata schrieb:
    PS:
    ... wie könnte man das evtl. testen, was schneller ist bzw. weniger RAM / CPU braucht?

    Mit Xdebug kann man sich den RAM-Verbrauch anzeigen lassen (Xdebug ist z.B. in EasyPHP schon integriert).

    Habe für dich drei verschiedene Methoden probiert:

    function count_filerows ($datei) { 
       $fdata = file($datei); 
       $rows = count($fdata); 
       unset($fdata); 
    return $rows; 
    }

    Maximaler RAM-Verbrauch: 4.029.952 Bytes
    Durchschnittliche Zeit: 0,0049575579166412 Sekunden

    function count_filerows ($datei) { 
       $fdata = file($datei); 
       $rows = count($fdata); 
    return $rows; 
    }

    Maximaler RAM-Verbrauch: 4.029.616 Bytes
    Durchschnittliche Zeit: 0,0049833731651306 Sekunden

    function count_filerows ($datei) { 
       return count(file($datei)); 
    }

    Maximaler RAM-Verbrauch: 4.029.192 Bytes
    Durchschnittliche Zeit: 0,0049318459033966 Sekunden

    Getestet wurde auf einem AMD Phenom II X3 740 @ 3 GHz, mit einer 1.548.405 Bytes großen Testdatei die 6.067 Zeilen hat.
    Pro Versuch habe ich die count_filerows() 1.000 mal durchlaufen lassen.

    Beitrag zuletzt geändert: 20.1.2012 18:43:00 von konakona
  6. hackyourlife

    Moderator Kostenloser Webspace von hackyourlife

    hackyourlife hat kostenlosen Webspace.

    @konakona:
    Du hast noch vergessen zu testen was die fgets-Variante an Speicher verbraucht.
  7. Hatte ich übersehen.
    function count_filerows ($file) { 
    $handle = fopen($file,'r');
    $i=0; 
       while ( fgets($handle) !== false ) { 
       $i++; 
       }
    fclose($handle);
    return $i; 
    }

    Maximaler RAM-Verbrauch: 344.760 Bytes
    Durchschnittliche Zeit: 0,018874094963074 Sekunden

    Selbe Testbedingungen wie oben.

    Beitrag zuletzt geändert: 23.1.2012 1:24:54 von konakona
  8. und einmal noch etwas minimalistischer ;)
    <?php
    echo ($f = file('<filepath>') ? count($f): 'Filename/Pfad ungültig';


    Beitrag zuletzt geändert: 23.1.2012 2:11:10 von hemiolos
  9. echo ($f = file('<filepath>')) ? count($f): 'Filename/Pfad ungültig';

    Maximaler RAM-Verbrauch: 6.171.328 Bytes
    Durchschnittliche Zeit: 0,0052886369228363 Sekunden
    (Selbe Testbedingungen wie oben.)

    Bitteschön. :thumb:
  10. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!