Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

reading file round and round

1 view
Skip to first unread message

cerr

unread,
Mar 19, 2010, 2:43:40 PM3/19/10
to
Hi There,

I read out the content from a file like:
foreach $line (<$handle>) {
print $line;
sleep(1);
}
whixh works well so far. But what I would like is, if the loop gets to
eof, it should start over on top again. How can i reset the reading
pointer back to the beginning of the file?

Thanks,
--
roN

cerr

unread,
Mar 19, 2010, 2:46:12 PM3/19/10
to

Do I actually need to close() and reopen my file or is there another
way to achieve this?

>
> Thanks,
> --
> roN

Ben Morrow

unread,
Mar 19, 2010, 2:55:57 PM3/19/10
to

Quoth cerr <ron.e...@gmail.com>:

Posting followups to yourself will not make people more likely to
respond.

You want perldoc -f seek, and the :seek exports from Fcntl.

Ben

C.DeRykus

unread,
Mar 19, 2010, 3:11:03 PM3/19/10
to

LOOP:
{


foreach $line (<$handle>)
{

...
}
seek($handle, 0, 0) or die ...
redo LOOP;
}

But if you're actually just trying to emulate a
tail -f, look at the seek doc (perldoc -f seek)
for details on the WHENCE argument. You could
pick up newly appended lines and avoid reading through the entire file
with each loop.

--
Charles DeRykus

Ben Morrow

unread,
Mar 19, 2010, 3:39:20 PM3/19/10
to

Quoth "C.DeRykus" <der...@gmail.com>:

>
> seek($handle, 0, 0) or die ...

Don't do that (I know perldoc -q tail recommends it, but it ought to be
updated). Use the constants from the Fcntl module, they're more
portable.

Ben

jl_...@hotmail.com

unread,
Mar 19, 2010, 5:27:01 PM3/19/10
to


If an infinite loop is what you want, you can always use the
Tie::File module (which you may already have in your installation of
Perl) and just increment the index variable, making sure to "mod" it
by the number of lines.

Here's an example:


#!/usr/bin/perl

use strict;
use warnings;

my $fileName = 'file.txt';

use Tie::File;
tie my @lines, 'Tie::File', $fileName
or die "Could not open file '$fileName': $!\n";

die "No lines found in '$fileName'.\n" unless @lines;

my $lineNum = 0;

while (1)
{
print $lines[$lineNum], "\n";
sleep(1);
}
continue
{
# Increment $lineNum, but make sure it doesn't exceed $#lines:
$lineNum++;
$lineNum %= @lines;
}

__END__


This solution may seem overkill for your example, but if you have a
more complex task where you'd rather traverse arrays instead of
manipulating file handles, Tie::File is quite nice.

Cheers,

-- Jean-Luc

Jürgen Exner

unread,
Mar 19, 2010, 6:09:00 PM3/19/10
to

perldoc -f seek

jue

Jürgen Exner

unread,
Mar 19, 2010, 6:11:42 PM3/19/10
to
"C.DeRykus" <der...@gmail.com> wrote:
>On Mar 19, 11:46 am, cerr <ron.egg...@gmail.com> wrote:
>> On Mar 19, 11:43 am, cerr <ron.egg...@gmail.com> wrote:
>>
>> > I read out the content from a file like:
>> > foreach $line (<$handle>) {
>> >           print $line;
>> >           sleep(1);
>> >         }
>> > whixh works well so far. But what I would like is, if the loop gets to
>> > eof, it should start over on top again. How can i reset the reading
>> > pointer back to the beginning of the file?
>>
>> Do I actually need to close() and reopen my file or is there another
>> way to achieve this?
>>
>>
>
>LOOP:
>{
> foreach $line (<$handle>)
> {
> ...
> }
> seek($handle, 0, 0) or die ...
> redo LOOP;
>}

Why not

while(1){


foreach $line (<$handle>){
{ ...
}

seek(...) or die ...
}

instead of that ugly label?

jue

Peter J. Holzer

unread,
Mar 20, 2010, 7:37:52 AM3/20/10
to

Are they really?

hp

Ben Morrow

unread,
Mar 20, 2010, 1:12:35 PM3/20/10
to

Quoth "Peter J. Holzer" <hjp-u...@hjp.at>:

Honestly? I've no idea :). In principle they might be, though, and
anyway a proper constant is always nicer than random magic numbers.

Ben

0 new messages