Dateien einlesen

Eine sehr häufig benutzte Funktion ist es Dateien einzulesen. Das kommt zum Beispiel bei kleineren Anwendungen vor, wo die Daten nicht in eine Datenbank geschrieben werden oder auch wenn eine Datenbank zu viel Aufwand wäre für diese kleinen Datenmengen. Ein viel wichtigeres Anwendungsgebiet ist das Caching. Dabei wird die Ausgabe von PHP-Scripts, die sicht nicht oft ändert, in eine statische HTML-Datei gespeichert und kann dann recht schnell aufgerufen werden. Wie schnell, das hängt von der Funktion ab, mit der man die abgespeicherte Datei einliest – und darum solls hier gehen.
Für das Einlesen von Dateien gibt es mehrere Funktionen in PHP, da wären

// der klassischeWeg über ein Filehandle
if ($handle = fopen ("readme.txt",'r')) { 
  $content = ''; 
  while (!feof($handle)) { 
    $content .= fgets ($handle); 
  } 
  fclose ($handle);
}
 
// zeilenweise in ein Array speichern mit file() und in einen String verwandeln mit implode()
$content = implode('',file("readme.txt"));
 
// direktes Einlesen des gesamten Dateiinhaltes per file_get_contents()
$content = file_get_contents("readme.txt");
 
//Ausgabe des Dateiinhaltes
echo $content;

Wenn man die Datei nicht weiter verarbeiten möchte sondern einfach nur einlesen und ausgeben, gibt es noch

readfile("readme.txt");

Man sieht, dass es einige Methoden gibt, diese Aufgabe zu lösen und alle arbeiten etwas anders, was sich auch bei der Performance bemerkbar macht.

Auswertung:
Im Test wurde eine 7 kb große Datei verwendet. Dabei kam als Ergebnis herasu:

Datei Gesamtlaufzeit durchschnittliche Laufzeit pro Durchlauf Verhältnis zur schnellsten Variante
result_dateilesen_
readfile.php
14.500851 s 1.450 ms 100 %
result_dateilesen_
file_get_contents.php
15.231903 s 1.523 ms 105 % (+ 5%)
result_dateilesen_
implode_file.php
16.623904 s 1.662 ms 114 % (+ 14%)
result_dateilesen_
fopen_fgets.php
18.136078 s 1.814 ms 125 % (+ 25%)

Hierbei ist readfile() Sieger. Aber wie gesagt, diese Funktion ist nur verwendbar, wenn man den Dateiinhalt nicht weiterverarbeiten möchte. Ansonsten ist file_get_contents die richtige Wahl.

Für große Dateien wendet sich das Blatt. Ich habe eine 1 MB große dll-Datei verwendet. Diese möchte ich natürlich nicht ausgeben, weshalb readfile() hier in der Praxis wahrscheinlich rausfällt, aber ich habe die Funktion trotzdem mit getestet. Man sieht aber, dass sich das Bild dann wendet:

Datei Gesamtlaufzeit durchschnittliche Laufzeit pro Durchlauf Verhältnis zur schnellsten Variante
result_dateilesen_
file_get_contents.php
67.977747 s 6.798 ms 100 %
result_dateilesen_
implode_file.php
196.202125 s 19.620 ms 288 % (+ 188%)
result_dateilesen_
fopen_fgets.php
213.797426 s 21.380 ms 314 % (+ 214 %)
result_dateilesen_
readfile.php
248.106760 s 24.811 ms 365 % (+ 265%)

Ein eindeutiger Sieg für file_get_contents(). Wo allerdings die Grenze ist, an der file_get_contents() die Funktion readfile() überholt, müsste selbst ausprobiert werden. Ich empfehle aber für die Praxis file_get_contents zu verwenden, da die Unterschiede bei kleinen Dateien moderat sind (bzw. wenn die Datei noch weiter verarbeitet werden soll, ist auch dort file_get_contents vorn) und bei größeren Dateien file_get_contents eindeutig weit vor den Kontrahenten liegt.

Auch zu diesem Beispiel gibt es natürlich die Quelltexte und die Ergebnisse für eine kleine Datei (7 kB) sowie die für eine große Datei (1 MB).

Jan hat 152 Beiträge geschrieben

3 Kommentare zu “Dateien einlesen

  1. Tim sagt:

    Man sollte file() nur anwenden, wenn man das Ergebnis in einem Array haben möchte, ansonsten immer file_get_contents() verwenden. Beide Funktionen unterscheiden sich nur in dem Ausgabeformat. file_get_contents() ist natürlich schneller weil der komplette Array implodiert werden muss, bevor man einen String hat.
    Ist readfile() schneller als file_get_contents(), wenn man readfile() in Verbindung mit ob_get_contents() verwendet?

    Gruß
    Tim

  2. Auch wenns schon ein wenig her ist sagt:

    [readfile 0 Bytes] => 5.042719
    [readfile 100 Bytes] => 5.206955
    [readfile 10 Bytes] => 5.214474
    [file_get_contents 0 Bytes] => 5.222806
    [implode_file 0 Bytes] => 5.267729
    [readfile 1000 Bytes] => 5.279982
    [file_get_contents 1000 Bytes] => 5.353576
    [file_get_contents 100 Bytes] => 5.383204
    [implode_file 10 Bytes] => 5.409459
    [file_get_contents 10 Bytes] => 5.423556
    [implode_file 100 Bytes] => 5.455674
    [file_get_contents 10000 Bytes] => 5.465499
    [implode_file 1000 Bytes] => 5.466741
    [implode_file 10000 Bytes] => 5.589660
    [readfile 10000 Bytes] => 10.434042

Eine Antwort schreiben

Ihre E-Mail-Adresse wird nicht veröffentlicht. Benötigte Felder sind markiert mit *

You may use these HTML tags and attributes: <a href=""> <blockquote cite=""> <pre lang=""> <b> <strong> <i> <em>