2009-08-11 3 views
1

Я хочу прочитать все из текстового файла и повторить его. Но в текстовом файле может быть больше строк, в то время как я читаю, поэтому я не хочу, чтобы скрипт вышел, когда он достиг конца файла, вместо этого я не буду ждать вечно для большего количества строк. Возможно ли это в php?Блокировка чтения файла в php?

+0

Это зависит от типа функциональности, на которую вы стремитесь. Выполняется ли этот сценарий в контексте запроса, поступающего из браузера? Это CLI-скрипт, который может работать бесконечно? –

+0

Является ли это скриптом PHP, который будет запускаться из командной строки или с веб-сервера? – Wade

+0

Сценарий командной строки, но как это важно? – Martin

ответ

0

Я решил.

Фокус в том, чтобы использовать fopen, и когда достигнуто eof, переместите курсор в предыдущую позицию и продолжайте читать оттуда.

<?php 
$handle = fopen('text.txt', 'r'); 
$lastpos = 0; 
while(true){ 
    if (!feof($handle)){ 
     echo fread($handle,8192); 
     flush(); 
     $lastpos = ftell($handle); 
    }else{ 
     fseek($handle,$lastpos); 
    } 
} 
?> 

Все еще потребляет довольно много процессора, хотя, не знаю, как это решить.

+0

Вы заняты циклом, конечно, он потребляет весь процессор. Попробуйте добавить 'usleep (50000)' после строки 'fseek'. Это будет спать в течение 50 мс, что значительно снизит использование вашего ЦП без заметного влияния на вашу задержку. Чтобы сделать еще лучше, вам нужно использовать inotify (при условии, что вы находитесь в системе, которая его поддерживает). – derobert

+0

Да, я знаю, что это из-за цикла, работает, но я не являюсь поклонником сна-решений. inotify, хотя, похоже, именно то, что я искал, я буду смотреть на это завтра. – Martin

1

Это всего лишь догадка, но попытайтесь передать (passthru) выход «хвост -f».

, но вам нужно будет найти способ сбросить() ваш буфер.


ИМХО намного лучше было бы создать сайт ajax.

прочитайте содержимое файла в массиве. сохраните количество строк в сеансе. распечатать содержимое файла.

Запуск ajax-запроса каждые x секунд скрипту, который проверяет файл, если количество строк больше, чем количество сеансов, добавьте результат на страницу.


можно использовать POPEN() inststed:

$f = popen("tail -f /where/ever/your/file/is 2>&1", 'r'); 
while(!feof($f)) { 
    $buffer = fgets($f); 
    echo "$buffer\n"; 
    flush(); 
    sleep(1); 
} 
pclose($f) 

сон очень важен, без него вы будете иметь 100% процессорного времени.

+0

На самом деле я сделал решение с хвостом, который работает, но он использует бесконечный цикл, который потребляет весь процессор, поэтому я хочу какой-то «блокирующий» вызов. Вызов каждого X секунд не достаточно, мне нужно в реальном времени, и это не сайт, поэтому нет ajax. – Martin

+0

'tail -f' - это« realtime »и не нуждается ни в петле, ни в php. – VolkerK

+0

Это всплывающее решение почти точно похоже на мое. Проблема заключается в том, что сон задерживает слишком большую задержку. – Martin

0

Фактически, когда вы «эхо», он переходит в буфер. Итак, вы хотите «добавить» новый контент, если он добавлен, пока браузер все еще получает выход. И это невозможно (но есть некоторые подходы к этому).

+0

Вы знаете, что есть флеш()? – Rufinus

0

Вы также можете использовать filemtime: вы получаете последнюю временную метку изменения, отправляете результат и в конце сравниваете снова сохраненную filemtime с текущей.

В любом случае, если вы хотите, чтобы сценарий работал одновременно с браузером (или клиентом), вы должны отправить вывод с помощью фрагментов (fread, flush), а затем проверить все изменения в конце. Если есть какие-либо изменения, повторно откройте файл и прочитайте его с последней позиции (вы можете получить позицию за пределами цикла while(!feof())).

Смежные вопросы