The script reads the lines from the file, here's the code:
#!/usr/bin/perl
use strict;
use warnings;
use AnyEvent;
open my $fh, '<', 'input.txt' or die "Can't open file: $!";
my $cv = AE::cv;
my $timer = AE::timer 0, 10, sub {
printf "TELL: %s EOF: %s\n", tell $fh, eof $fh;
print while <$fh>;
};
$cv->recv;
If I add lines through cat, then the script reads the new lines. But if I edit the file through a vim editor, then the script does not see any new lines in the file and issues an EOF. Why does the script behave this way and do not see new lines?
Output of the script:
$ perl test.pl
TELL: 0 EOF:
row_1
row_2
row_3
TELL: 18 EOF: 1
TELL: 18 EOF: 1
TELL: 18 EOF:
row_4
TELL: 24 EOF:
row_5
TELL: 30 EOF: 1
TELL: 30 EOF: 1
TELL: 30 EOF: 1
TELL: 30 EOF: 1
The initial content of the input.txt:
row_1
row_2
row_3
Added via cat:
$ cat >> input.txt
row_4
row_5
Added via vim:
$ vim input.txt
row_6
row_7
Most likely, you'll have to make your program open the file, read a small chunk, close the file, and then wait for a bit before reading again. Even then, there's no guarantee that you won't have the file open when the writing process tries to write.
To read from a text fileUse the ReadAllText method of the My. Computer. FileSystem object to read the contents of a text file into a string, supplying the path. The following example reads the contents of test.
'r+' opens the file for both reading and writing. On Windows, 'b' appended to the mode opens the file in binary mode, so there are also modes like 'rb', 'wb', and 'r+b'. Also reading then writing works equally well using 'r+b' mode, but you have to use f. seek(0) between f.
The shell's >>
directive opens the existing file, while vim
creates a new file with the same name as the old one, leaving your program reading an a now-anonymous file.
$ touch a
$ perl -MFile::stat -e'my $qfn = $ARGV[0]; my $s = stat($qfn) or die $!; printf "%s:%s\n", $s->dev, $s->ino' a
2065:1084527165
$ cat >>a
foo
$ perl -MFile::stat -e'my $qfn = $ARGV[0]; my $s = stat($qfn) or die $!; printf "%s:%s\n", $s->dev, $s->ino' a
2065:1084527165
$ vim a
$ perl -MFile::stat -e'my $qfn = $ARGV[0]; my $s = stat($qfn) or die $!; printf "%s:%s\n", $s->dev, $s->ino' a
2065:1084520254
You need to re-open the file.
#!/usr/bin/perl
use strict;
use warnings;
use AnyEvent;
use Fcntl qw( SEEK_SET );
my $cv = AE::cv;
my $qfn = $ARGV[0];
my $last_pos = 0;
my $timer = AE::timer 0, 10, sub {
open(my $fh, '<', $qfn)
or die("Can't open file: $!\n");
seek($fh, $last_pos, SEEK_SET)
or die("Can't seek: $!\n");
printf "TELL: %s EOF: %s\n", tell $fh, eof $fh;
print while <$fh>;
( $last_pos = tell($fh) ) >= 0
or die("Can't tell: $!\n");
};
$cv->recv;
Outputs:
$ echo foo >a
$ perl a.pl a
TELL: 0 EOF:
foo
TELL: 4 EOF: 1
TELL: 4 EOF: 1 echo bar >>foo
TELL: 4 EOF:
bar
TELL: 8 EOF: 1
TELL: 8 EOF: 1 Used vim to change the file to "The quick brown fox"
TELL: 8 EOF:
k brown fox
TELL: 20 EOF: 1
^C
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With