在大量文本数据中读取第N行最后一行. 类似sed -n "10P" xxx.txt

通过SplFileObject

最简单的方案,通过seek,current
注意,从0行开始

<?php

function getLine($file,$num=0){

    $fp=new SplFileObject($file,'r');
    $fp->seek($num);

    return $fp->current();
}

fgets方式

通过fgets逐行

function getLine2(string $file,int $num=0)
{
    $fp=fopen($file,'r');
    // 之前写的defer函数
    defer(function () use($fp){
        @fclose($fp);
    },$_);
    $n=0;
    //try {
        while (!feof($fp)) {
            if ($n == $num) {
                return fgets($fp);
            }
            fgets($fp);
            $n++;
        }
    //} finally {
    //    fclose($fp);
    //}

    return  null;
}

最后几行

获取最后几行,一般用于日志查看.类似tail

使用 seek

function getLastLine(string $file){
    $fObj=new SplFileObject($file,'r');
    $fObj->seek(PHP_INT_MAX);
    $fObj->seek($fObj->key());
    return $fObj->current();
}

通过fseek,SEEK_END跳转到文件最后一个字符,从后往前遍历一行.最后再倒转字符.

function getLastLine2(string $file){
    $fp=fopen($file,'r');
    $c=-1;
    $line='';
    fseek($fp,$c,SEEK_END);
    while (!feof($fp)){
        $char=fgetc($fp);
        fseek($fp,--$c,SEEK_END);
        if($char!="\n" && $char!==false ){
            $line.=$char;
        }
        if($char=="\n" || feof($fp)){
            break;
        }
    }
    @fclose($fp);
    return strrev($line);
}

性能getLastLine2

1G文件,相关20多倍.

image-20230926165059256

原作者:阿金
本文地址:https://hi-arkin.com/archives/php-tail-last.html

标签: php fgets SplFileObject sed tail

(本篇完)

评论