zoukankan      html  css  js  c++  java
  • php如何快速读取大文件

    <?php
    
    namespace BcremerLineReader;
    
    final class LineReader
    {
        /**
         * Prevent instantiation
         */
        private function __construct() {}
    
        /**
         * @param string $filePath
         * @return Generator
         * @throws InvalidArgumentException if $filePath is not readable
         */
        public static function readLines(string $filePath): Generator
        {
            if (!$fh = @fopen($filePath, 'r')) {
                throw new InvalidArgumentException('Cannot open file for reading: ' . $filePath);
            }
    
            return self::read($fh);
        }
    
        /**
         * @param string $filePath
         * @return Generator
         * @throws InvalidArgumentException if $filePath is not readable
         */
        public static function readLinesBackwards(string $filePath): Generator
        {
            if (!$fh = @fopen($filePath, 'r')) {
                throw new InvalidArgumentException('Cannot open file for reading: ' . $filePath);
            }
    
            $size = filesize($filePath);
    
            return self::readBackwards($fh, $size);
        }
    
        /**
         * @param resource $fh
         * @return Generator
         */
        private static function read($fh): Generator
        {
            while (false !== $line = fgets($fh)) {
                yield rtrim($line, "
    ");
            }
    
            fclose($fh);
        }
    
        /**
         * Read a file from the end using a buffer.
         *
         * This is way more efficient than using the naive method
         * of reading the file backwards byte by byte looking for
         * a newline character.
         *
         * @see http://stackoverflow.com/a/10494801/147634
         * @param resource $fh
         * @param int $pos
         * @return Generator
         */
        private static function readBackwards($fh, int $pos): Generator
        {
            $buffer = null;
            $bufferSize = 4096;
    
            if ($pos === 0) {
                return;
            }
    
            while (true) {
                if (isset($buffer[1])) { // faster than count($buffer) > 1
                    yield array_pop($buffer);
                    continue;
                }
    
                if ($pos === 0) {
                    yield array_pop($buffer);
                    break;
                }
    
                if ($bufferSize > $pos) {
                    $bufferSize = $pos;
                    $pos = 0;
                } else {
                    $pos -= $bufferSize;
                }
                fseek($fh, $pos);
                $chunk = fread($fh, $bufferSize);
                if ($buffer === null) {
                    // remove single trailing newline, rtrim cannot be used here
                    if (substr($chunk, -1) === "
    ") {
                        $chunk = substr($chunk, 0, -1);
                    }
                    $buffer = explode("
    ", $chunk);
                } else {
                    $buffer = explode("
    ", $chunk . $buffer[0]);
                }
            }
        }
    }

     github参考

     如何读取大文件

  • 相关阅读:
    基于jQuery的鼠标悬停时放大图片的效果制作
    让document.write的广告无阻塞的加载
    浅谈DOM事件的优化
    前端自动化构建和发布系统的设计
    parseQueryString
    元素缩放
    apply用法
    3D旋转
    CSS居中的多种方法
    System Center Configuration Manager 2016 域准备篇(Part2)
  • 原文地址:https://www.cnblogs.com/webclz/p/10709557.html
Copyright © 2011-2022 走看看