Maison > développement back-end > Problème PHP > Comment lire certaines lignes de gros fichiers en php

Comment lire certaines lignes de gros fichiers en php

藏色散人
Libérer: 2023-03-13 20:30:01
original
2126 Les gens l'ont consulté

Comment implémenter PHP pour lire certaines lignes d'un gros fichier : 1. Utilisez directement la fonction file pour opérer ; 2. Appelez la commande Linux tail pour afficher les dernières lignes ; . Via PHP La fonction stream_get_line implémente la lecture.

Comment lire certaines lignes de gros fichiers en php

L'environnement d'exploitation de cet article : système windows7, version PHP7.1, ordinateur DELL G3

php Comment lire certaines lignes d'un gros fichier ?

Introduction à diverses méthodes de lecture de gros fichiers avec PHP

La lecture de gros fichiers a toujours été un casse-tête Nous pouvons utiliser diverses fonctions pour utiliser directement PHP pour lire de petits fichiers, mais lorsqu'il s'agit d'articles volumineux, ce sera le cas. a constaté que les méthodes couramment utilisées ne peuvent pas être utilisées normalement ou prennent trop de temps et sont bloquées. Examinons les solutions au problème de lecture de fichiers volumineux en PHP. J'espère que les exemples pourront vous aider.

En PHP, lors de la lecture de fichiers, le moyen le plus rapide est d'utiliser certaines fonctions telles que file et file_get_contents. Quelques lignes de code simples peuvent compléter à merveille les fonctions dont nous avons besoin. Mais lorsque le fichier exploité est un fichier relativement volumineux, ces fonctions peuvent s'avérer insuffisantes. Ce qui suit commencera par expliquer les méthodes d'exploitation couramment utilisées lors de la lecture de fichiers volumineux.

Exigences :

Il existe un fichier journal de 800 M avec environ 5 millions de lignes. Utilisez PHP pour renvoyer le contenu des dernières lignes.

Méthode d'implémentation :

1. Utilisez directement la fonction de fichier pour fonctionner

Étant donné que la fonction de fichier lit tout le contenu dans la mémoire en même temps, PHP empêche certains programmes mal écrits d'occuper trop de mémoire et de provoquer une mémoire système insuffisante, provoquant le crash du serveur, donc par défaut l'utilisation maximale de la mémoire est limitée à 16 Mo. Ceci est défini via memory_limit = 16M dans php.ini. Si cette valeur est définie sur -1, l'utilisation de la mémoire n'est pas limitée.

Ce qui suit est un morceau de code qui utilise file pour extraire la dernière ligne de ce fichier :

<?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;
?>
Copier après la connexion

 L'exécution de l'intégralité du code prend 116,9613 (s).

 Ma machine dispose de 2 Go de mémoire. Lorsque j'appuie sur F5 pour exécuter, le système devient gris et ne récupère qu'après près de 20 minutes. On voit que les conséquences de la lecture d'un fichier aussi volumineux directement dans la mémoire sont graves, alors je. Je n'en parlerai pas ici. En dernier recours, memory_limit ne peut pas être réglé trop haut, sinon vous devrez appeler la salle informatique pour réinitialiser la machine.

2. Appelez directement la commande Linux tail pour afficher les dernières lignes

Sous la ligne de commande Linux, vous pouvez directement utiliser tail -n 10 access.log pour afficher facilement les dernières lignes du fichier journal. utilisez PHP pour appeler la commande tail, exécutez le code PHP comme suit :

<?php
  $file = &#39;access.log&#39;;
  $file = escapeshellarg($file); // 对命令行参数进行安全转义
  $line = `tail -n 1 $file`;
  echo $line;
?>
Copier après la connexion

L'exécution complète du code prend 0,0034 (s)

3 Utilisez directement le fseek de PHP pour effectuer des opérations sur les fichiers

Cette méthode est la méthode la plus courante, elle le fait. ne nécessite pas que tout le contenu du fichier soit lu, mais exploité directement via des pointeurs, l'efficacité est donc assez efficace. Lorsque vous utilisez fseek pour exploiter des fichiers, il existe de nombreuses méthodes différentes, et l'efficacité peut être légèrement différente. Voici deux méthodes couramment utilisées :

Méthode 1

Tout d'abord, recherchez le dernier EOF du fichier via fseek. position de départ de la dernière ligne, prenez les données de cette ligne, puis trouvez la position de départ de la ligne suivante, puis prenez la position de cette ligne, et ainsi de suite, jusqu'à ce que la ligne $num soit trouvée.

Le code d'implémentation est le suivant

<?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
?>
Copier après la connexion

 L'exécution de l'intégralité du code prend 0,0095 (s)

Méthode 2

  Toujours en utilisant fseek pour lire à partir de la fin du fichier, mais cette fois il ne lit pas un par un , mais une lecture une par une, chaque fois qu'une donnée est lue, les données lues sont placées dans un buf, puis le nombre de caractères de nouvelle ligne (\n) est utilisé pour déterminer si les dernières lignes de données $num ont été lire.

Le code d'implémentation est le suivant

<?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;
?>
Copier après la connexion

L'exécution entière du code prend 0,0009(s).

Troisième méthode

<?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));
?>
Copier après la connexion

L'exécution entière du code prend 0,0003(s)

La quatrième méthode, la fonction stream_get_line de PHP, lit rapidement, et il faut environ 20 secondes pour lire un gros fichier contenant 500 000 données ! L'exemple de code est le suivant

$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;
 // } 
  
 }
Copier après la connexion

Apprentissage recommandé : "Tutoriel vidéo PHP"

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
php
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal