PHP는 Linux 명령 tail -f를 구현합니다.
오늘 문득 예전에 누군가가 나에게 물었던 질문이 떠올랐습니다. Linux 명령 tail -f를 PHP를 통해 구현하는 방법을 여기에서 분석하고 구현하겠습니다.
생각해보면 아주 간단합니다. 파일 크기가 변경되었는지 확인하기 위해 루프를 통해 파일의 변경된 부분을 출력합니다. , 거기에 많은 세부 사항이 있을 것입니다. 여기에 자세한 분석이 있습니다.
초기 파일이 너무 크거나 내용이 너무 많이 변경된 경우
이때 많은 내용이 한꺼번에 출력되어 선명하게 보이지 않을 수 있으므로 여기서는 임계값 8192입니다. 콘텐츠 길이가 이 임계값을 초과하면 마지막 8192바이트만 출력되므로 넓은 영역 새로 고침으로 인해 가시성이 불분명해지는 문제가 없습니다.
파일 크기 변화를 감지하는 방법
이 질문이 이 프로그램의 핵심입니다. 이 부분의 성능에 따라 성공 여부가 결정됩니다. 여기에서의 구현은 다음과 같습니다.
파일 핸들 $fp를 엽니다. 여기에서 파일 핸들은 전체 프로세스에서 한 번만 열고 닫아야 하므로 외부에 배치해야 합니다. 고리.
현재 파일 크기 file_size 및 file_size_new를 0으로 초기화합니다.
file_size_new 파일 크기는 루프에서 업데이트됩니다. PHP에서 파일 크기를 가져오기 전에, 파일 상태 캐시를 지우려면 cleanstatcache() 함수를 실행해야 합니다. 그렇지 않으면 오류가 발생할 수 있습니다. 파일 크기를 얻는 데 편차가 발생합니다.
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);
결과는 다음과 같습니다