Делать Perl для печати во время выполнения? - PullRequest
2 голосов
/ 27 июля 2011

У меня есть этот кусок кода:

#!/usr/local/bin/perl
use strict;
open my $output, ">", "D:\\abc.txt";
for ( my $i = 0; $i < 10; $i++ )
{
    print $output $i . "\n";
    sleep(5);
}

Удивительно, но когда я запускаю его и открываю abc.txt в течение 50 секунд, пока машина работает, я не вижу текущий вывод.Я ожидаю, что через 13 секунд, например, файл будет содержать «0 \ n1 \ n2», но по какой-то причине этого не происходит.

Я просмотрел другие фрагменты кода, которые я написал, и фактическисделайте это, но я не смог найти никакой разницы.

Не могли бы вы мне помочь?

Заранее спасибо.

1 Ответ

6 голосов
/ 27 июля 2011

Если вы прочитаете статью Марка Джейсона Доминуса, Страдая от буферизации , вы увидите, что настройка $| применяется к текущему дескриптору файла.Если вы установите $| = 1; в верхней части вашего скрипта, вы, вероятно, отключите буферизацию для STDOUT.Тем не менее, ваш скрипт пишет в файловый дескриптор с именем $output.

Вы должны поместить эту строку в свой скрипт сразу после вызова open.

select( ( select( $output ), $|=1 )[0] ); # borrowed from the Suffering from Buffering article.

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

Это также задокументировано в perlfaq5 , который входит в стандартную комплектацию при каждой полной установке Perl.

В качестве наилучшей практики вам, вероятно, следует либо ставить or die $! после всех вызовов ввода-вывода, либо use autodie; в верхней части сценария.Я говорю «вероятно», потому что всегда есть исключения, но вряд ли это одно из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...