柳暗花明笔记

    php生成器yield妙用,php读取大文件最后几行实例

    所属分类:[ php&web ] 猫哲学家 发表于:2017-12-20 16:14 浏览:77

    function memoryUsed()
    {
        return round(memory_get_peak_usage()/1024/1024, 2) . " M\n";
    }
    function getBigFileLine($filename)
    {
        $file = fopen($filename, 'r');
        while (($line = fgets($file)) !== false) {
            yield $line;
        }
        fclose($file);
    }
    function arrayQueue(&$a, $val, $key, $n = 3)
    {
        $b = [$key => $val];
        if (count($a) < $n) {
            $a[] = $b;
        } else {
            array_shift($a);
            array_push($a, $b);
        }
    }

    echo memoryUsed();

    $logFile = __DIR__ . '/bitfile.txt';

    // 制造大文件,也不算大400多M
    // for ($i = 1; $i < 5000000; $i++) {
    //     echo $i.',';
    //     error_log(date('[Y-m-d H:i:s]') . ' line ' . $i . ' ebay自动化刊登的今天不搞,写个wish的listing同步' . PHP_EOL, 3, $logFile);
    // }

    // $fileData = file_get_contents($logFile);
    $fileData = getBigFileLine($logFile);
    $a = [];
    foreach ($fileData as $i => $line) {
        // echo $line;
        arrayQueue($a, $line, $i);
    }

    print_r($a);
    echo memoryUsed();

    总结之:

    使用生成器 yield来读取php大文件占用内存级少,几乎不占用,但用file_get_contents读取471M的文件占用的内存也472M,基本上是1M对1M的使用

    ===========class版本===========

    class readBigFileLastLines
    {
        public $_logFile = '';
        public function __construct($file = '')
        {
            $this->_logFile = $file;
        }
        public function memoryUsed()
        {
            return round(memory_get_peak_usage()/1024/1024, 2) . " M\n";
        }
        public function getBigFileLine()
        {
            $file = fopen($this->_logFile, 'r');
            while (($line = fgets($file)) !== false) {
                yield $line;
            }
            fclose($file);
        }
        public function arrayQueue(&$a, $val, $key, $n = 3)
        {
            $b = [$key => $val];
            if (count($a) < $n) {
                $a[] = $b;
            } else {
                array_shift($a);
                array_push($a, $b);
            }
        }    
        // 制造大文件,也不算大400多M
        public function createBigFile()
        {
            for ($i = 1; $i < 5000000; $i++) {
                echo $i.',';
                error_log(date('[Y-m-d H:i:s]') . ' line ' . $i . ' ebay自动化刊登的今天不搞,写个wish的listing同步' . PHP_EOL, 3, $this->_logFile);
            }
        }
        public function read($n = 3)
        {
            echo $this->memoryUsed();
            $fileData = $this->getBigFileLine($this->_logFile);
            $a = [];
            foreach ($fileData as $i => $line) {
                // echo $line;
                $this->arrayQueue($a, $line, $i, $n);
            }
            print_r($a);
            echo $this->memoryUsed();
        }
    }

    $reader = (new readBigFileLastLines(__DIR__ . '/bitfile.txt'))->read();

    标签: php 
    上一编文章 修改X-Powered-By方法,隐藏X-Powered-By方法 下一编文章 一个好用的命令git stash
    最近文章
    发表评论