Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

seek function always returns true

by rudyg123 (Initiate)
on Jun 19, 2007 at 22:03 UTC ( #622118=perlquestion: print w/replies, xml ) Need Help??
rudyg123 has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm very new to Perl programming so please excuse me if this problem I'm having sounds basic. I am writing a script to parse a binary file. The file contains hex data that is formatted in such a way that I can jump anywhere in the file to read data. The program prompts the user for input asking which record in the file to read. There is a possibility that the record is not contained in the file. This can happen if the file is too small (not enough records to satisfy the input parameter request). The following code is executed and my problem is that the die is never executed. The seek is always returning a 1. I have run test cases where I know the record I am asking for is greater than the contents of the file. In other words the offset in bytes from the beginning of the file is greater than the number of bytes in the file. Why doesn't the seek return 0.
seek(FIN, $start_pc, 0) or die "seek:$!";

Replies are listed 'Best First'.
Re: seek function always returns true
by Joost (Canon) on Jun 19, 2007 at 22:24 UTC
      I had heard of files with holes but didn't realise the implicatons for seek. Looks like you do get the read error on Solaris.

      $ ls -l xxxx -rw-r--r-- 1 johngg users 639 Jun 19 23:26 xxxx $ perl -le ' > open $in, q{<}, q{xxxx} or die $!; > seek $in, 1000, 0 == tell $in or die q{bad seek}; > print tell $in; > 10 == read $in, $buf, 10 or die q{bad read}; > print tell $in; > print $buf;' 1000 bad read at -e line 5. $



      Same on Windows (SetFilePointerEx API).
Re: seek function always returns true
by graff (Chancellor) on Jun 20, 2007 at 02:20 UTC
    It's easy enough to get the current size of the file:
    my $current_file_size = -s $file_name;
    So you just need to have that value, and check it against the number that the user provides as the offset to go to:
    if ( $start_pc >= $current_file_size ) { warn sprintf( "Your requested offset (%d) is past EOF (%d)\n", $start_pc, $current_file_size ); # and do something else, like prompt for new input }
    Of course, if the user is asking for fixed-length-record $n, you'd want to say that the requested $n is greater than the number of records in the file (file size divided by record size, which, in an ideal world, would always be an integer value).
      Thanks for all who responded to my question. I didn't realize how seek actually worked until you guys posted these responses. I didn't know that seek() could actually go beyond the EOF. I tried the code that you guys provided and it worked for me. The key for me was doing the read(). If you try and read past the EOF you do get an error. RG
Re: seek function always returns true
by crouchingpenguin (Priest) on Jun 20, 2007 at 13:17 UTC
    See eof:
    open(my $fh, '>', 'f00') or die $!; seek($fh, 100, 0) or die "seek:$!"; print "eof!" if eof($fh); close($fh);

    "Never be afraid to try something new. Remember, amateurs built the ark. Professionals built the Titanic."

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://622118]
Approved by shigetsu
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (7)
As of 2018-05-23 14:05 GMT
Find Nodes?
    Voting Booth?