In diesem Artikel werden hauptsächlich die verschiedenen Methoden zum Lesen großer Dateien in PHP vorgestellt.
Das Lesen großer Dateien war schon immer ein Problem. Wir verwenden PHP, um kleine Dateien lesen zu können Wenn Sie jedoch zu einem großen Artikel gelangen, werden Sie feststellen, dass die häufig verwendeten Methoden nicht normal verwendet werden können oder zu lange dauern und stecken bleiben . Lösung, ich hoffe, das Beispiel kann Ihnen helfen.
In PHP ist es beim Lesen von Dateien am schnellsten, einige Funktionen wie file und file_get_contents zu verwenden. Es kann wunderbar mit nur wenigen Codezeilen vervollständigt werden. Wenn es sich bei der zu bearbeitenden Datei jedoch um eine relativ große Datei handelt, reichen diese Funktionen möglicherweise nicht aus. Im Folgenden werden zunächst die häufig verwendeten Betriebsmethoden beim Lesen großer Dateien erläutert.
Anforderungen:
Es gibt eine 800 MB große Protokolldatei mit etwa 5 Millionen Zeilen. Verwenden Sie PHP, um den Inhalt der letzten paar Zeilen zurückzugeben.
Implementierungsmethode:
1. Verwenden Sie direkt die Dateifunktion, um zu arbeiten
Da die Dateifunktion den gesamten Inhalt auf einmal in den Speicher einliest und PHP einige Fehler verhindert Wenn geschriebene Programme zu viel Speicher belegen, führt dies zu einem Absturz des Servers. Daher ist die maximale Speichernutzung durch „memory_limit = 16M“ in php.ini festgelegt -1 , die Speichernutzung ist unbegrenzt.
Das Folgende ist ein Codestück, das file verwendet, um die letzte Zeile dieser Datei zu extrahieren:
<?php ini_set('memory_limit', '-1'); $file = 'access.log'; $data = file($file); $line = $data[count($data) - 1]; echo $line; ?>
Die gesamte Codeausführung dauerte 116,9613 (S) .
Mein Rechner verfügt über 2 GB Speicher, wenn ich F5 drücke, um ihn auszuführen, wird das System erst nach fast 20 Minuten wiederhergestellt. Es ist ersichtlich, dass das direkte Einlesen einer so großen Datei schwerwiegende Folgen hat Als letzten Ausweg darf „memory_limit“ nicht zu hoch eingestellt werden, andernfalls müssen Sie den Computerraum anrufen, um die Maschine zurückzusetzen.
2. Rufen Sie direkt den Linux-Befehl tail auf, um die letzten Zeilen anzuzeigen.
Unter der Linux-Befehlszeile können Sie tail -n 10 access.log direkt verwenden, um die letzten Zeilen des Protokolls einfach anzuzeigen Sie können PHP direkt verwenden, um den Befehl tail aufzurufen und den PHP-Code wie folgt auszuführen:
<?php $file = 'access.log'; $file = escapeshellarg($file); // 对命令行参数进行安全转义 $line = `tail -n 1 $file`; echo $line; ?>
Die gesamte Codeausführung dauert 0,0034 (s)
3. Direkte Verwendung von PHPs fseek zur Ausführung von Dateioperationen
Diese Methode ist die gebräuchlichste Methode. Sie muss nicht den gesamten Inhalt der Datei lesen, sondern arbeitet direkt über Zeiger, sodass die Effizienz recht effizient ist . Bei der Verwendung von fseek zum Bearbeiten von Dateien gibt es viele verschiedene Methoden, und die Effizienz kann geringfügig unterschiedlich sein. Die folgenden zwei häufig verwendeten Methoden sind:
Methode 1
Suchen Sie zuerst die Datei über fseek. Das letzte EOF. Suchen Sie dann die Startposition der letzten Zeile, rufen Sie die Daten dieser Zeile ab, ermitteln Sie dann die Startposition der nächsten Zeile, übernehmen Sie dann die Position dieser Zeile und so weiter, bis die Zeile $num gefunden wird.
Der Implementierungscode lautet wie folgt
<?php $fp = fopen($file, "r"); $line = 10; $pos = -2; $t = " "; $data = ""; while ($line > 0) { while ($t != "\n") { fseek($fp, $pos, SEEK_END); $t = fgetc($fp); $pos--; } $t = " "; $data .= fgets($fp); $line--; } fclose($fp); echo $data ?>
Die gesamte Codeausführung dauert 0,0095 (s)
Methode 2
Wird immer noch verwendet fseek Die Methode beginnt mit dem Lesen am Ende der Datei, aber dieses Mal liest sie nicht Stück für Stück, sondern liest Stück für Stück. Jedes Mal, wenn ein Datenelement gelesen wird, werden die gelesenen Daten in einen Puffer gestellt und dann Zeilenumbruchzeichen (\ n), um festzustellen, ob die letzten $num Datenzeilen gelesen wurden.
Der Implementierungscode lautet wie folgt
<?php $fp = fopen($file, "r"); $num = 10; $chunk = 4096; $fs = sprintf("%u", filesize($file)); $max = (intval($fs) == PHP_INT_MAX) ? PHP_INT_MAX : filesize($file); for ($len = 0; $len < $max; $len += $chunk) { $seekSize = ($max - $len > $chunk) ? $chunk : $max - $len; fseek($fp, ($len + $seekSize) * -1, SEEK_END); $readData = fread($fp, $seekSize) . $readData; if (substr_count($readData, "\n") >= $num + 1) { preg_match("!(.*?\n){" . ($num) . "}$!", $readData, $match); $data = $match[0]; break; } } fclose($fp); echo $data; ?>
Die gesamte Codeausführung dauert 0,0009(s).
Methode 3
<?php function tail($fp, $n, $base = 5) { assert($n > 0); $pos = $n + 1; $lines = array(); while (count($lines) <= $n) { try { fseek($fp, -$pos, SEEK_END); } catch (Exception $e) { fseek(0); break; } $pos *= $base; while (!feof($fp)) { array_unshift($lines, fgets($fp)); } } return array_slice($lines, 0, $n); } var_dump(tail(fopen("access.log", "r+"), 10)); ?>
Die gesamte Codeausführung dauert 0,0003(s)
Methode 4, PHPs stream_get_line-Funktion, schnell Beim Lesen dauert das Lesen einer großen Datei mit 500.000 Daten etwa 20 Sekunden! Der Beispielcode lautet wie folgt:
$fp = fopen('./iis.log', 'r'); //文件 while (!feof($fp)) { //for($j=1;$j<=1000;$j++) { //读取下面的1000行并存储到数组中 $logarray[] = stream_get_line($fp, 65535, "\n"); // break; // } }
Zusammenfassung: Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Lernen aller hilfreich sein wird.
Verwandte Empfehlungen:
Detaillierte Erläuterung der Vererbung und Verwendungsbeispiele von Klassen in PHP
So implementieren Sie die Paging-Anzeigefunktion von Daten in PHP
phpMehrere Möglichkeiten, den physischen Pfad des Website-Stammverzeichnisses abzurufen
Das obige ist der detaillierte Inhalt vonAusführliche Erklärungen und Beispiele verschiedener Methoden zum Lesen großer Dateien in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!