Home > Archive > PERL Beginners > August 2005 > open file for read and append
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
open file for read and append
|
|
| Dan Klose 2005-08-23, 7:55 am |
|
Hello,
I have a script where I need to open a file, read from it sequentially,
and append items to the file as I go along, continuing to read these
items as I go. But seems I can't open the file for read and append at
the same time. Does anyone have any ideas?
Many thanks.
--
Daniel Klose
PhD Student - Taylor Group
Mathematical Biology
National Institute for Medical Research
The Ridgeway
Mill Hill
London
NW7 1AA
| |
| Xavier Noria 2005-08-23, 7:55 am |
| On Aug 23, 2005, at 12:34, Dan Klose wrote:
> I have a script where I need to open a file, read from it
> sequentially,
> and append items to the file as I go along, continuing to read these
> items as I go. But seems I can't open the file for read and append at
> the same time. Does anyone have any ideas?
Tie::File to the rescue!
See for instance this example (foo.pl):
use strict;
use warnings;
use Tie::File;
tie my @fh, "Tie::File", "foo.txt" or die $!;
my $nlines = @fh;
my $i = 0;
foreach my $line (@fh) {
push @fh, $line;
last if ++$i == $nlines;
}
and this shell session:
% cat foo.txt
foo
bar
% perl foo.pl
% cat foo.txt
foo
bar
foo
bar
-- fxn
| |
| Muthukumar 2005-08-23, 7:55 am |
| > > I have a script where I need to open a file, read from it
>=20
Is it possible to open a file +>> mode to read and append?=20
Like,
Test.log
hi
bye
#!/usr/bin/perl
open FD, +>>"test.log"
while (<FD> )
{
print FD;
}
close FD;
Thanks.
-Muthu
| |
| Xavier Noria 2005-08-23, 6:56 pm |
| On Aug 23, 2005, at 12:49, Muthukumar wrote:
>
> Is it possible to open a file +>> mode to read and append?
Yes, this is documented in perlopentut for instance.
> Like,
>
> Test.log
> hi
> bye
>
> #!/usr/bin/perl
> open FD, +>>"test.log"
> while (<FD> )
> {
> print FD;
> }
> close FD;
Only it doesn't work that easy.
In Unix (I don't know how portable is this explanation) the
difficulty comes from the fact that a file has a metadata associated
called a _file offset_. This is an offset in the file that indicates
the position from which the next read or write will occur. The
important thing here to note is that there is only ONE offset used
for BOTH operations.
For example, if the offset of FH points to byte 37, the next <FH>
will try to read a line starting at byte 37, and the next print will
print starting at byte 37 and overwriting whatever was there, if
anything. Either read or write, whatever is called first, will start
at 37.
After each read or write the file offset is adjusted behind the
scenes accordingly to point past the recently fetched or written
bytes. In the previous example, after, say, printing "foo\n" into FH,
the offset is adjusted and now points to byte 41, where the next read
or write will occur.
In Perl tell() return the current offset of a filehandle, and see
what happens when you open in append mode:
% wc -c foo.txt
12 foo.txt
% perl -le 'open FOO, "+>>", "foo.txt" or die $!; print tell FOO'
12
See? The file offset points _to the end_ of the file, we are ready to
_write_.
If you try your code you'll see NOTHING is printed at all. This is
because the file offset is at the end of the file, as seen above, we
try to read a line in the while condition, and since there's nothing
to read at the end of the file we don't even enter the while block.
The file offset can be changed manually with s (), and in +>> mode
the programmer s s to read (writes automatically s to append),
he handles the file offset by hand.
Tie::File takes care of those details for you, really helpful as you
see.
-- fxn
|
|
|
|
|