2015-09-21 2 views
0

У меня есть скрипт perl, для которого я создал файл журнала, и все операции, которые этот скрипт сделает, будут записываться в файл журнала.обработчик файла застревает во время вывода вывода в текстовый файл в Perl

Это было хорошо, я внес некоторые изменения, чтобы исправить некоторые проблемы, но теперь я получаю странную проблему, Файловый обработчик застревает во время записи файла журнала, и он не обновляет файл журнала до тех пор, пока я не буду я выхожу из сценария с опцией exit (x).

Например, мой сценарий предлагает выполнить

  1. Extract
  2. Validate
  3. Резервное копирование

    X. Выход

теперь я бегу Extraction и обновляет журнал. Но в то время как extrcation является complted я открыл файл журнала, и я могу увидеть последнюю строку

Date: XYZ file extracted.  
Date: XXXX file is preparing to extract 
Date: 

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

Я не понимаю, почему он застревает, и это происходит для всех других вариантов. Раньше он работал нормально. Я просто использую обработчик и печать для перенаправления.

open FILE, ">>log.txt" 

## DO some thing 

print FILE $output; 

может кто-нибудь сказать мне, что может быть проблемой?

+0

Вы печатаете строку журнала в одном утверждении 'print' или двух? Это 'do_something(); print "Date: $ log_message \ n"; 'или это' print 'Date: "; сделай что-нибудь(); print $ log_message; '? – Schwern

+0

Попробуйте включить автозапуск, чтобы избежать буферизации: '$ | ++;' – xxfelixxx

ответ

0

Вы столкнулись с file buffering. Это нормальная вещь, которую делают большинство языков программирования. Поскольку запись на диск или терминал выполняется медленно, каждый оператор печати не обязательно записывается немедленно. Вывод обычно сохраняется в памяти (т. Е. «Буферизован») и записывается при достижении определенной суммы или определенного символа.

По умолчанию STDERR не буферизирован. STDOUT терминалу обычно буферизуется в строке, то есть он будет писать, когда видит новую строку. Файлы буферизуются в блоках, обычно 4K или 8K, это зависит от вашей системы.

Для файла журнала имеет смысл отключить эту буферизацию. Все дескрипторы файлов отвечают на методы IO :: Handle, поэтому для этого используйте метод IO::Handleautoflush.

# Because you've forgotten to check if the file opened. 
use autodie; 

open my $fh, ">>", $log_file; 
$fh->autoflush(1);