Maison php教程 php手册 PHP几个快速读取大文件例子

PHP几个快速读取大文件例子

Jun 02, 2016 am 09:13 AM
catch fopen preg_match substr

下面给各位整理几个PHP读取大文件例子,本文章讲到的是测试文章在800M的数据哦,更大的文件小编没有测试过哦。

在PHP中,对于文件的读取时,最快捷的方式莫过于使用一些诸如file、file_get_contents之类的函数,简简单单的几行代码就能很漂亮的完成我们所需要的功能。但当所操作的文件是一个比较大的文件时,这些函数可能就显的力不从心, 下面将从一个需求入手来说明对于读取大文件时,常用的操作方法。

需求

有一个800M的日志文件,大约有500多万行, 用PHP返回最后几行的内容。

实现方法

1. 直接采用file函数来操作

由于 file函数是一次性将所有内容读入内存,而PHP为了防止一些写的比较糟糕的程序占用太多的内存而导致系统内存不足,使服务器出现宕机,所以默认情况下限制只能最大使用内存16M,这是通过php.ini里的 memory_limit = 16M 来进行设置,这个值如果设置-1,则内存使用量不受限制。

下面是一段用file来取出这具文件最后一行的代码:

<?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

整个代码执行完成耗时 116.9613 (s)。

我机器是2个G的内存,当按下F5运行时,系统直接变灰,差不多20分钟后才恢复过来,可见将这么大的文件全部直接读入内存,后果是多少严重,所以不在万 不得以,memory_limit这东西不能调得太高,否则只有打电话给机房,让reset机器了。

2.直接调用Linux的 tail 命令来显示最 后几行

在Linux命令行下,可以直接使用 tail -n 10 access.log 很轻易的显示日志文件最后几行,可以直接用PHP来调用tail命令,执行PHP代码如下:

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

整个代码执行完成耗时 0.0034 (s)

3. 直接使用PHP的 fseek 来进行文件操作

这种方式是最为普遍的方式,它不需要将文件的内容全部读入内容,而是直接通过指针来操作,所以效率是相当高效的。在使用fseek来对文件进行操作时,也有多种不同的方法,效率可能也是略有差别的,下面是常用的两种方法:

方法一

首先通过fseek找到文件的最后一位EOF,然后找最后一行的起始位置,取这一行的数据,再找次一行的起始位置, 再取这一行的位置,依次类推,直到找到了$num行。

#实现代码如下

<?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

整个代码执行完成耗时 0.0095 (s)

方法二

还是采用fseek的方式从文件最后开始读,但这时不是一位一位的读,而是一块一块的读,每读一块数据时,就将读取后的数据放在一个buf里,然后通过换 行符(\n)的个数来判断是否已经读完最后$num行数据。

#实现代码如下

<?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

整个代码执行完成耗时 0.0009(s)。

方法三

<?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

整个代码执行完成耗时 0.0003(s)


文章网址:

随意转载^^但请附上教程地址。

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

Article chaud

Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD
Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Article chaud

Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD
Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Tags d'article chaud

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment résoudre PHP Avertissement : fopen() : échec d'ouverture du flux : aucun fichier ou répertoire de ce type Comment résoudre PHP Avertissement : fopen() : échec d'ouverture du flux : aucun fichier ou répertoire de ce type Aug 19, 2023 am 10:44 AM

Comment résoudre PHP Avertissement : fopen() : échec d'ouverture du flux : aucun fichier ou répertoire de ce type

Comment résoudre PHP Avertissement : fopen() : l'opération SSL a échoué dans file.php à la ligne X Comment résoudre PHP Avertissement : fopen() : l'opération SSL a échoué dans file.php à la ligne X Aug 25, 2023 am 09:22 AM

Comment résoudre PHP Avertissement : fopen() : l'opération SSL a échoué dans file.php à la ligne X

Comment résoudre l'avertissement PHP : fopen() : échec d'ouverture du flux : autorisation refusée Comment résoudre l'avertissement PHP : fopen() : échec d'ouverture du flux : autorisation refusée Aug 20, 2023 pm 01:45 PM

Comment résoudre l'avertissement PHP : fopen() : échec d'ouverture du flux : autorisation refusée

Utilisation de la fonction fopen dans Matlab Utilisation de la fonction fopen dans Matlab Nov 28, 2023 am 11:03 AM

Utilisation de la fonction fopen dans Matlab

Comment utiliser fopen, fwrite et fclose en php pour les opérations sur les fichiers ? Comment utiliser fopen, fwrite et fclose en php pour les opérations sur les fichiers ? Jun 01, 2023 am 08:46 AM

Comment utiliser fopen, fwrite et fclose en php pour les opérations sur les fichiers ?

En langage C, utilisez la fonction fopen() pour ouvrir un fichier existant en mode écriture En langage C, utilisez la fonction fopen() pour ouvrir un fichier existant en mode écriture Aug 27, 2023 pm 10:33 PM

En langage C, utilisez la fonction fopen() pour ouvrir un fichier existant en mode écriture

PHP renvoie la valeur ASCII du premier caractère de la chaîne PHP renvoie la valeur ASCII du premier caractère de la chaîne Mar 21, 2024 am 11:01 AM

PHP renvoie la valeur ASCII du premier caractère de la chaîne

PHP renvoie la chaîne de la position de début à la position de fin d'une chaîne dans une autre chaîne PHP renvoie la chaîne de la position de début à la position de fin d'une chaîne dans une autre chaîne Mar 21, 2024 am 10:31 AM

PHP renvoie la chaîne de la position de début à la position de fin d'une chaîne dans une autre chaîne

See all articles