So lesen Sie bestimmte Zeilen großer Dateien in PHP

藏色散人
Freigeben: 2023-03-13 20:30:01
Original
2076 Leute haben es durchsucht

So implementieren Sie PHP, um bestimmte Zeilen einer großen Datei zu lesen: 1. Verwenden Sie direkt die Dateifunktion, um die letzten paar Zeilen anzuzeigen. 3. Verwenden Sie PHPs fseek, um Dateioperationen auszuführen . Durch PHPs Die stream_get_line-Funktion implementiert das Lesen.

So lesen Sie bestimmte Zeilen großer Dateien in PHP

Die Betriebsumgebung dieses Artikels: Windows7-System, PHP7.1-Version, DELL G3-Computer

php Wie lese ich bestimmte Zeilen einer großen Datei?

Einführung in verschiedene Methoden zum Lesen großer Dateien mit PHP

Das Lesen großer Dateien war schon immer ein Problem. Wir können PHP verwenden, um kleine Dateien direkt zu lesen, aber wenn es um große Artikel geht, ist dies der Fall Ich habe festgestellt, dass die häufig verwendeten Methoden nicht normal verwendet werden können oder zu lange dauern und stecken bleiben. Schauen wir uns die Lösungen für das Problem des Lesens großer Dateien in PHP an. Ich hoffe, die Beispiele können Ihnen helfen.

In PHP ist es beim Lesen von Dateien am schnellsten, einige Funktionen wie file und file_get_contents zu verwenden. Ein paar einfache Codezeilen können die von uns benötigten Funktionen wunderbar vervollständigen. 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 liest, verhindert PHP, dass einige schlecht geschriebene Programme zu viel Speicher belegen und zu einer unzureichenden Systemspeicherung führen. Dies führt zum Absturz des Servers, sodass die maximale Speichernutzung standardmäßig auf 16 MB begrenzt ist. Dies wird durch „memory_limit = 16 MB“ in php.ini festgelegt. Wenn dieser Wert auf -1 gesetzt ist, ist die Speichernutzung nicht begrenzt.

Das Folgende ist ein Codestück, das file verwendet, um die letzte Zeile dieser Datei zu extrahieren:

<?php
  ini_set(&#39;memory_limit&#39;, &#39;-1&#39;);
  $file = &#39;access.log&#39;;
  $data = file($file);
  $line = $data[count($data) - 1];
  echo $line;
?>
Nach dem Login kopieren

 Die Ausführung des gesamten Codes dauert 116,9613 (s).

 Wenn ich F5 zum Ausführen drücke, wird das System erst nach fast 20 Minuten wiederhergestellt. Es ist ersichtlich, dass das direkte Einlesen einer so großen Datei schwerwiegende Folgen hat Ich werde hier nicht darauf eingehen. 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 paar Zeilen anzuzeigen.

Unter der Linux-Befehlszeile können Sie tail -n 10 access.log direkt verwenden, um die letzten paar Zeilen der Protokolldatei anzuzeigen Verwenden Sie PHP, um den Tail-Befehl aufzurufen, und führen Sie den PHP-Code wie folgt aus:

<?php
  $file = &#39;access.log&#39;;
  $file = escapeshellarg($file); // 对命令行参数进行安全转义
  $line = `tail -n 1 $file`;
  echo $line;
?>
Nach dem Login kopieren

 Die gesamte Codeausführung dauert 0,0034 (s)

3. Verwenden Sie fseek von PHP direkt, um Dateioperationen auszuführen. Diese Methode ist die gebräuchlichste Methode Es ist nicht erforderlich, dass der gesamte Inhalt der Datei eingelesen wird, sondern der Betrieb direkt über einen Zeiger erfolgt, sodass die Effizienz recht effizient ist. Bei der Verwendung von fseek zum Bearbeiten von Dateien gibt es viele verschiedene Methoden, und die Effizienz kann leicht unterschiedlich sein. Die folgenden sind zwei häufig verwendete Methoden:

Methode 1

Suchen Sie zuerst den letzten EOF der Datei über fseek Startposition der letzten Zeile, nimm die Daten dieser Zeile, finde dann die Startposition der nächsten Zeile, nimm dann die Position dieser Zeile und so weiter, bis die $num-Zeile 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
?>
Nach dem Login kopieren

 Die Ausführung des gesamten Codes dauert 0,0095 (s)

Methode 2

  Ich verwende immer noch fseek, um vom Ende der Datei zu lesen, aber dieses Mal wird nicht einzeln gelesen , aber eins nach dem anderen Beim Lesen werden jedes Mal, wenn ein Datenelement gelesen wird, die gelesenen Daten in einen Puffer gestellt und dann anhand der Anzahl der Zeilenumbrüche (\n) ermittelt, ob die letzten $num Datenzeilen vorhanden sind lesen.

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;
?>
Nach dem Login kopieren

Die gesamte Codeausführung dauert 0,0009(s).

Methode drei

<?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));
?>
Nach dem Login kopieren

Die gesamte Codeausführung dauert 0,0003(s)

Methode vier, die stream_get_line-Funktion von PHP, liest schnell und das Lesen einer großen Datei mit 500.000 Daten dauert etwa 20 Sekunden! Der Beispielcode lautet wie folgt

$fp = fopen(&#39;./iis.log&#39;, &#39;r&#39;); //文件 
while (!feof($fp)) { 
 //for($j=1;$j<=1000;$j++) {     //读取下面的1000行并存储到数组中 
 $logarray[] = stream_get_line($fp, 65535, "\n"); 
    // break;
 // } 
  
 }
Nach dem Login kopieren

Empfohlenes Lernen: „

PHP-Video-Tutorial

Das obige ist der detaillierte Inhalt vonSo lesen Sie bestimmte Zeilen großer Dateien in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
php
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage