您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 开发 > WEB开发 >
    如何在不会招致效劳器宕机的状况下,用PHP读取大文件(2)
    时间:2017-12-05 21:10 来源:网络整理 作者:网络 浏览:收藏 挑错 推荐 打印

        return round($bytes, $precision) . " " . $units[$pow]; 

     

    print formatBytes(memory_get_peak_usage()); 

     

    // from reading-files-line-by-line-1.php 

     

    function readTheFile($path) { 

        $lines = []; 

        $handle = fopen($path, "r"); 

     

        while(!feof($handle)) { 

            $lines[] = trim(fgets($handle)); 

        } 

     

        fclose($handle); 

        return $lines; 

     

    readTheFile("shakespeare.txt"); 

     

    require "memory.php"

    我们读取一个文本文件为莎士比亚选集。文件大小为5.5MB,内存占用峰值为12.8MB。如今让我们用一个生成器来读取每一行:

    // from reading-files-line-by-line-2.php 

     

    function readTheFile($path) { 

        $handle = fopen($path, "r"); 

     

        while(!feof($handle)) { 

            yield trim(fgets($handle)); 

        } 

     

        fclose($handle); 

     

    readTheFile("shakespeare.txt"); 

     

    require "memory.php"

    文本文件大小不变,但内存运用峰值只是393KB。即使我们能把读取到的数据做一些事情也并不意味着什么。也许我们可以在看到两条空白时把文档联系成块,像这样:

    // from reading-files-line-by-line-3.php 

     

    $iterator = readTheFile("shakespeare.txt"); 

     

    $buffer = ""

     

    foreach ($iterator as $iteration) { 

        preg_match("/\n{3}/", $buffer, $matches); 

     

        if (count($matches)) { 

            print "."

            $buffer = ""

        } else { 

            $buffer .= $iteration . PHP_EOL; 

        } 

     

    require "memory.php"

    猜到我们运用了多少内存吗?我们把文档联系为1216块,依然只运用了459KB的内存,这能否让你诧异?思索到生成器的性质,我们运用的最多内存是运用在 迭代中 我们需求存储的最大文本块。在本例中,最大的块为101985字符。

    我曾经撰写了 运用生成器提示功用 和 Nikita Popov的迭代器库 ,假设你感兴味就去看看吧!

    生成器还有其它用途,但是最清楚的益处就是高功用读取大文件。假设我们需求处置这些数据,生成器能够是最好的办法。

    管道间的文件

    在我们不需求处置数据的状况下,我们可以把文件数据传递到另一个文件。通常被称为管道(大约是由于我们看不到除了两端的管子外面,当然,它也是不透明的),我们可以经过运用流办法完成。让我们先写一个脚本从一个文件传到另一个文件。这样我们可以测量内存的占用状况:

    // from piping-files-1.php 

     

    file_put_contents( 

        "piping-files-1.txt", file_get_contents("shakespeare.txt"

    ); 

     

    require "memory.php"

    不出所料,这个脚本运用更多的内存来停止文本文件复制。这是由于它读取(和保留)文件内容在内存中,直到它被写到新文件中。关于小文件这种办法也许没成绩。当为更大的文件时,就 捉襟见肘了…

    让我们尝试用流(管道)来传送一个文件到另一个:

    // from piping-files-2.php 

     

    $handle1 = fopen("shakespeare.txt""r"); 

    $handle2 = fopen("piping-files-2.txt""w"); 

     

    stream_copy_to_stream($handle1, $handle2); 

     

    fclose($handle1); 

    fclose($handle2); 

     

    require "memory.php"

    这段代码稍微有点生疏。我们翻开了两文件的句柄,第一个是只读形式,第二个是只写形式,然后我们从第一个复制到第二个中。最后我们封锁了它,也许使你诧异,内存只占用了393KB

    这似乎很熟习。像代码生成器在存储它读到的每一行代码?那是由于第二个参数 fgets 规则了每行读多少个字节(默许值是-1或许直到下一行为止)。

    (责任编辑:admin)