Wie funktionieren fopen() und fgets() intern?
Andreas Korthaus
- php
Halllo!
Ich schreibe gerade ein Script, welches eigentlich nur die 2. und 3. Zeile aus Datendateien mit 10.000 und mehr Zeilen braucht, und das von über 100 Dateien und die einzelnen Dateien haben oft über 1 MB.
Sind also z.B. 200MB, von denen mich aber nur weniger als 100 KB interessieren.
Wie programmiere ich das jetzt möglichst effektiv? Daher interessiert mich mal der Background, wie die Funktionen fopen und fget implementiert sind. Leider verstehe ich selbst den C Quelltext nicht wirklich, da blicke ich einfach nicht durch, aber vielleicht weiß da ja hier jemqand was zu, da ich auch annemhme das das in verschiedenen Programmiersprachen ähnlich implementiert ist.
Bisher habe ich das einlesen aus Faulheit meistens mit file() gemacht, aber das ist wohl denkbar schlecht in diesem Fall, da so alles eingelesen, und in eiien Array geschreben wird, das brauche ich gar nicht.
Ich vermute das fopen nichts mit der Dateigröße zu tun hat, da es nur einen Zeiger auf die Datei zurückgibt, oder?
fgets: "string fgets ( resource handle [, int length])"
Vermutlich sollte ich die zu lesende Länge so kurz wie möglich setzen.
Was genau ist eigentlich eine recource? Sicher kenne ich die Beschreibung im Manual, undich arbeite seit eh und je erfolgreich damit, aber was ist das? Woher kommt es das wenn ich
$line1 = fgets($fp);
$line2 = fgets($fp);
ausführe, das nach der Ersten "Verwendung" der Recource diese verändert wird, also dass automatisch der Zeiger auf die näcgte Zeile gesetzt wird?
Wenn ich jetzt Zeile 2 und 3 will mache ich das mit
$fp= fopen("file.data");
fgets($fp,100);
$line2 = fgets($fp,100);
$line3 = fgets($fp,100);
fclose($fp);
Ist das so wie Ihr es auch machen würdet?
Da die Daten einfach durch Leerzeichen getrennt sind, verwende ich vermutlich lieber:
fgetcsv($fp,100," ");
Viele Grüße
Andreas
Marko,
Background, wie die Funktionen fopen und fget implementiert sind. Leider verstehe ich selbst den C Quelltext nicht wirklich, da blicke ich einfach nicht durch, aber vielleicht weiß da ja hier jemqand was zu, da ich auch annemhme das das in verschiedenen Programmiersprachen ähnlich implementiert ist.
Also PHP benutzt natürlich C Bibliotheksfunktionen, wobei da noch 2 Sachen vermengt werden, das öffnen von Sockets und Dateien ist in C nämlich etwas anderes.In C hast Du dann Standardschnittstellen für Dateioperationen, deren Implementierung dann aber Systemabhängig ist (Linux/Unix verwendet z.B. intern ganz andere Dateisystemzugriffsarten wie Windows). Aber um den ganzen Implementierungskäse musst Du dich eigentlich als Programmierer garnicht kümmern, es sei denn Du willst PHP selbst erweitern, was für Dein Vorhaben aber Unsinn wäre.
Ich vermute das fopen nichts mit der Dateigröße zu tun hat, da es nur einen Zeiger auf die Datei zurückgibt, oder?
Grundsätzlich ja.
fgets: "string fgets ( resource handle [, int length])"
Vermutlich sollte ich die zu lesende Länge so kurz wie möglich setzen.
Ja.
Was genau ist eigentlich eine recource?
Naja ne Resource kann alles mögliche sein damit ist eigentlich die Datei oder der Socket gemeint mit dem Du arbeitest.
$line1 = fgets($fp);
$line2 = fgets($fp);ausführe, das nach der Ersten "Verwendung" der Recource diese verändert wird, also dass automatisch der Zeiger auf die näcgte Zeile gesetzt wird?
Die Resource selbst wird eigentlich nicht verändert, der feine Unterschied ist, dass $fp ein Resourcehandler ist. Ein Resourcehandler ist eine Datenstruktur, die Informationen über die Resource enthält, $fp ist ein Pointer auf eine Tabelle, die irgendwo im Speicher steht. In dieser Tabelle steht dann z.B. wo die Daten physikalisch zu finden sind, und es existiert ein Dateizeiger, der durch ein fgets verändert wird, und angibt von welcher Stelle in der Datei als nächstes gelesen wird. Aber die Daten der Datei auf der Festplatte werden natürlich nicht verändert, nur der Dateizeiger in der Dateihandler Datenstruktur. Wenn Du es Dich ganz genau interessiert wie das abläuft müsstest Du ziemlich tief in die Betriebssystemebene reinschauen, meine Beschreibung war jetzt auch nur eine vereinfachte Abstraktion, wie genau der Dateizugriff oder der Socketzugriff auf Betriebsystemebene abläuft ist noch etwas komplizierter und Systemabhängig. Für Deine praktische ANwendung aber auch irrelevant.
$fp= fopen("file.data");
fgets($fp,100);
$line2 = fgets($fp,100);
$line3 = fgets($fp,100);
fclose($fp);
Ist das so wie Ihr es auch machen würdet?
Da die Daten einfach durch Leerzeichen getrennt sind, verwende ich vermutlich lieber:
fgetcsv($fp,100," ");
Ja eigentlich schon, also wenn es so läuft würde ich das auch nicht anders machen.
Gruss
Marko
Hallo!
Danke für Deine Erklärungen, hat mir geholfen!
Grüße
Andreas