• PHP实现linux命令tail -f


    PHP实现linux命令tail -f

    今天突然想到之前有人问过我的一个问题,如何通过PHP实现linux中的命令tail -f,这里就来分析实现下。

    这个想一想也挺简单,通过一个循环检测文件,看文件的大小是否有变化,如果有变化,输出文件变化的部分,当然了这里面会有好多的细节,这里具体分析下。

    如果初始文件太大或者改变内容太多

    这个时候一下输出好多内容可能看不清,因此我这里设置了一个阈值8192,当内容长度超过这个阈值的时候,只输出最后面的8192个字节,这样就不会出现大面积的刷新导致看不清的问题。

    如何检测文件大小的变化

    这个问题是这个程序的核心,能不能成功,性能的好坏就靠这部分了。
    我在这里的实现是下面这样:

    • 打开文件句柄$fp,这里要注意,这里的文件句柄全程需中只打开一次关闭一次,因此要将他放在循环的外面。
    • 初始化当前文件大小file_sizefile_size_new都为0。
      • 循环里面更新file_size_new文件大小,这里要注意,php中获取文件大小之前一定要运行函数clearstatcache(),清除文件状态缓存,否则获取文件大小可能会有偏差。
      • 计算add_size = file_size_new - file_size,看文件大小是否有变化,如果有变化,将文件指针移动到指定位置,然后输出新加的内容,更新file_size值为new_file_size
      • usleep(50000),睡眠1/20秒。

    代码实现

    #!/usr/bin/env php 
    <?php
    if(2 != count($argv)){
        fwrite(
            STDERR,
            "调用格式错误!使用格式 ./tail filename".PHP_EOL
        );  
        return 1;
    }
    
    $file_name      = $argv[1];
    define("MAX_SHOW", 8192);
    
    $file_size      = 0;
    $file_size_new  = 0;
    $add_size       = 0;
    $ignore_size    = 0;
    $fp = fopen($file_name, "r");
    while(1){
        clearstatcache();
        $file_size_new  = filesize($file_name);
        $add_size       = $file_size_new - $file_size;
        if($add_size > 0){ 
            if($add_size > MAX_SHOW){
                $ignore_size    = $add_size - MAX_SHOW;
                $add_size       = MAX_SHOW;
                fseek($fp, $file_size + $ignore_size);
            }   
            fwrite(
                STDOUT,
                fread($fp, $add_size)
            );  
            $file_size  = $file_size_new;
        }
        usleep(50000);
    }
    
    fclose($fp);
    

    代码实现这里第一行的#!/usr/bin/env php 是告诉可执行文件,可执行文件php在系统PATH中查找,这样的好处就是移植性好。

    2016-02-22 11:28:51改进

    查了PHP官方手册,fseek函数这里可以改进改进,这个函数还接受第三个参数,表示偏移指针的类型,默认是SEEK_SET,从开始偏移,还可以设置为SEEK_CUR,表示从当前位置偏移,因此这里改为fseek($fp, $ignore_size, $ignore_size);

    下面是结果

  • 相关阅读:
    EJB到底是什么,真的那么神秘吗??
    An Assembly Language
    Memory Layout (Virtual address space of a C process)
    手机测试用例-游戏测试用例
    手机测试用例-工具箱测试用例
    手机测试用例-输入法测试用例
    手机测试用例-时钟测试用例
    手机测试用例-多媒体测试用例
    手机测试用例-设置测试用例
    手机测试用例-通话记录测试用例
  • 原文地址:https://www.cnblogs.com/iforever/p/5202197.html
Copyright © 2020-2023  润新知