17

I opened a file to read from line by line:

open(FH,"<","$myfile") or die "could not open $myfile: $!";
while (<FH>)
{
    # ...do something
}

Later on in the program, I try to re-read the file (walk thru the file again):

while (<FH>)
{
    # ...do something
}

and realized that it is as if the control within file is at the EOF and will not iterate from first line in the file.... is this default behavior? How to work around this? The file is big and I do not want to keep in memory as array. So is my only option is to close and open the file again?

zb226
  • 7,475
  • 4
  • 37
  • 64
rajeev
  • 967
  • 5
  • 19
  • 38

2 Answers2

26

Use seek to rewind to the beginning of the file:

seek FH, 0, 0;

Or, being more verbose:

use Fcntl;
seek FH, 0, SEEK_SET;

Note that it greatly limits the usefulness of your tool if you must seek on the input, as it can never be used as a filter. It is extremely useful to be able to read from a pipe, and you should strive to arrange your program so that the seek is not necessary.

William Pursell
  • 174,418
  • 44
  • 247
  • 279
5

You have a few options.

  • Reopen the file handle
  • Set the position to the beginning of the file using seek, as William Pursell suggested.
  • Use a module such as Tie::File, which lets you read the file as an array, without loading it into memory.
TLP
  • 61,960
  • 8
  • 84
  • 140
  • regarding Tie::File i noted a comment (lost link) about BerkeleyDB on stackoverflow - in the context of reading very large files, without putting them in RAM at once. i felt, for now seek is enough. thanks again! – rajeev Aug 20 '12 at 19:43
  • 1
    @rajeev It is a very nice module, and it is part of the core installation from v5.7.3. I would say that the "standard" solution would be to simply reopen the file handle. You don't even need to close the file handle first, as that is done automatically. – TLP Aug 20 '12 at 19:49