Recipe 8.12 Using Random-Access I/O

8.12.1 Problem

You have to read a binary record from the middle of a large file but don't want to read a record at a time to get there.

8.12.2 Solution

Once you know the record's size, multiply it by the record number to get the byte address, and then seek to that byte address and read the record:

$ADDRESS = $RECSIZE * $RECNO;
seek(FH, $ADDRESS, 0) or die "seek:$!";
read(FH, $BUFFER, $RECSIZE);

8.12.3 Discussion

The Solution assumes the first record has a RECNO of 0. If you're counting from one, use:

$ADDRESS = $RECSIZE * ($RECNO-1);

This is best applied to binary data. Applying it to text files assumes you have a constant character width and constant line length. This rules out most Unicode encodings, any kind of Windows text file, and any text file where lines can have different lengths.

8.12.4 See Also

The seek function in perlfunc(1) and in Chapter 29 of Programming Perl; Recipe 8.13