开发者

File handles in Perl

开发者 https://www.devze.com 2023-02-05 22:05 出处:网络
Instead of the typical file handle I am used to: open INPUT, $input; while ($line = <INPUT>) { ....

Instead of the typical file handle I am used to:

open INPUT, $input;
while ($line = <INPUT>) {
    ....
}
close INPUT;

How do I retrieve a pointer to the line in a file so that I can advance these pointers at wiil? I'm trying to create two pointers to their corresponding sorted files so that I can advance pointers based on whether the line in one file is "less" or "greater" than the line in the other.

Note: Assu开发者_运维知识库me input files are BIG.


If I understand you correctly,

perldoc -f tell

Note that you want to tell just before reading a line to get the beginning position for the line.

The function to return to a given position is seek.

Alternatively, Tie::File will let you treat a file as an array of lines, with some clever management behind the scenes.


Why not store in an array?

my @lines1 = <INPUT1>;
my @lines2 = <INPUT2>;

Here's an example on ysth's seek/tell suggestion, which is probably more what you want if the files are too big: http://www.nntp.perl.org/group/perl.beginners/2007/12/msg97522.html


Given the answer to my comment, then you need to revise your logic to something like (pseudo-code):

open Master;
open Transaction;

# Get initial records?
read first Master;
read first Transaction;

BATCH_LOOP:
while (!eof(Master) && !eof(Transaction))
{
     while (Master.ID < Transaction.ID && !eof(Master))
     {
           write Master;
           read next Master;
     }
     if (Master.ID > Transaction.ID)
     {
           report Missing Master for Transaction;
           read next Transaction;
           next BATCH_LOOP;
     }
     # Master.ID == Transaction.ID
     Update Master from Transaction;
     read next Transaction;
}

# At most one of the following two loop bodies is executed
while (!eof(Master))
{
     read next Master;
     write Master;
}

while (!eof(Transaction))
{
     Report Missing Master;
     read next Transaction;
}

Double (and triple) check the logic - it was written on the fly around distractions. But it is close to what you need.

Use lexical file handles:

open my $master, "<", $master_file or die "Failed to open master file $master_file ($!)";
open my $trans,  "<", $trans_file  or die "Failed to open transaction file $trans_file ($!)";

You can read those independently of each other.

0

精彩评论

暂无评论...
验证码 换一张
取 消