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参考

     如何读取大文件

  • 相关阅读:
    C知识(#一些笔记)
    我整理的Python规则(2)
    我整理的Python代码规则
    教你如何通俗易懂的了解深度学习知识
    c#中委托和事件(续)(转)
    c#中的委托和事件(转)
    .Net neatupload上传控件实现文件上传的进度条
    C#常用日期格式处理转换[C#日期格式转换大全
    C#string常用函数总结
    数据库08版本如何移动到05的数据中
  • 原文地址:https://www.cnblogs.com/webclz/p/10709557.html
Copyright © 2011-2022 走看看