note
almut
<blockquote>
<i> ... This worked for me. </i>
</blockquote>
<p> Really? It doesn't for me — at least not with the file handles being opened to regular text files. </p>
<p> Buffering is only one of the problems here. The deeper issue is that with respect to <c>select</c>, regular disk files are <i>defined</i> to always be readable (even though the operation might block for a few milliseconds until the read head of the disk is positioned).
In other words, if the file pointer is at the end of the file, <c>select</c> would still indicate that the file is readable. And because <c>->getline()</c> reads until the next newline <i>or <c>eof</c></i>, you could get partial lines (not terminated by a newline). </p>
<p> So, while the following sort of works, it doesn't fulfill the OP's requirement to read <i>entire</i> lines. </p>
<c>
#!/usr/bin/perl
use strict;
use warnings;
use IO::Handle;
use IO::Select;
my ($fname1, $fname2) = qw(1.txt 2.txt);
open my $fh1, $fname1 or die $!;
open my $fh2, $fname2 or die $!;
my $slct = IO::Select->new();
$slct->add($fh1, $fh2);
while (1) {
my @canBeRead = $slct->can_read();
foreach my $fh (@canBeRead) {
my $line = $fh->getline();
if (defined $line) {
my $fname = $fh == $fh1 ? $fname1 : $fname2;
print "$fname: $line\n"
} else {
sleep 1; # be nice
}
}
}
</c>
<p> It's effectively the same as </p>
<c>
use IO::Handle;
my ($fname1, $fname2) = qw(1.txt 2.txt);
open my $fh1, $fname1 or die $!;
open my $fh2, $fname2 or die $!;
while (1) {
foreach my $fh ($fh1, $fh2) {
my $line = $fh->getline();
if (defined $line) {
my $fname = $fh == $fh1 ? $fname1 : $fname2;
print "$fname: $line\n"
} else {
sleep 1; # be nice
}
}
}
</c>
850549
850558