PHP實現linux命令tail -f
PHP實現linux命令tail -f
今天突然想到之前有人問過我的一個問題,如何通過PHP實現linux中的命令 tail -f ,這里就來分析實現下。
這個想一想也挺簡單,通過一個循環檢測文件,看文件的大小是否有變化,如果有變化,輸出文件變化的部分,當然了這里面會有好多的細節,這里具體分析下。
如果初始文件太大或者改變內容太多
這個時候一下輸出好多內容可能看不清,因此我這里設置了一個閾值 8192 ,當內容長度超過這個閾值的時候,只輸出最后面的 8192 個字節,這樣就不會出現大面積的刷新導致看不清的問題。
如何檢測文件大小的變化
這個問題是這個程序的核心,能不能成功,性能的好壞就靠這部分了。我在這里的實現是下面這樣:
- 打開文件句柄 $fp ,這里要注意,這里的文件句柄全程需中只打開一次關閉一次,因此要將他放在循環的外面。
- 初始化當前文件大小 file_size 和 file_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);
下面是結果
本文由用戶 cnnuabelule 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!