Насколько я понимаю, ваша программа в основном выглядит следующим образом:
open(my $fh,'>','foobar.txt');
print $fh "foo\n";
print "bar\n"; # prints to STDOUT
И затем вы используете его таким образом, что STDOUT перенаправляется в оболочке на тот же файл, который уже открыт в вашей программе:
$ perl test.pl > foobar.txt
Откроется два независимых дескриптора файла для одного и того же файла: один внутри вашей программы, а другой внутри оболочки, где вы запускаете программу.Оба дескриптора файла управляют своей собственной позицией файла для записи, начинаются с позиции 0 и продвигают позицию после каждой записи.
Поскольку эти файловые дескрипторы независимы друг от друга, им будет все равно, будут ли другие файловые дескрипторы иметь дело с этим файлом в настоящее время, независимо от того, находятся ли эти другие файловые дескрипторы внутри или вне программы.Это означает, что эти записи будут перезаписывать друг друга.
В дополнение к этому также выполняется внутренняя буферизация, т. Е. Каждая print
сначала приводит к записи в некоторый внутренний буфер и может немедленно привести к записи вдескриптор файла.Когда данные записываются в дескриптор файла, зависит от режима дескриптора файла, то есть небуферизованного, строкового буфера или буфера определенного размера.Это делает результат вроде непредсказуемым.
Если вы не хотите такого поведения, но по-прежнему хотите записывать в один и тот же файл, используя несколько файловых дескрипторов, вам лучше использовать режим добавления, то есть открывать с >>
вместо >
в обоих кодах Perlи оболочка.Это гарантирует, что все данные будут добавлены в конец файла, а не записаны в положение файла, поддерживаемое дескриптором файла.Таким образом, данные не будут перезаписаны.Кроме того, вы можете захотеть сделать дескрипторы файлов небуферизованными, чтобы данные в файле были в том же порядке, что и операторы print
, где это сделано:
open(my $fh,'>>','foobar.txt');
$fh->autoflush(1); # make $fh unbuffered
$|=1; # make STDOUT unbuffered
print $fh "foo\n";
print "bar\n"; # prints to STDOUT
$ perl test.pl >> foobar.txt