jeanluca has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

Is it possible to go from one place to another place in a file using File::Binary?. Well, I tried the following
$fb = File::Binary->new("./myFile"); .... $fb->seek(10) ; # go from place A to B
This generates the following error:
usage: $io->seek(POS, WHENCE) at /usr/lib/perl5/site_perl/5.8.7/File/B +inary.pm line 166
The documentations didn't help me very much with this one:(
Any suggestions ?

Thanks in advance
Luca

Replies are listed 'Best First'.
Re: File::Binary:howto goto a position in file
by dragonchild (Archbishop) on Mar 12, 2006 at 13:30 UTC
    use Fcntl 'SEEK_SET'; $fb->seek( 10, SEEK_SET );
    seek() takes two parameters - the offset (or POS) and how that offset should be interpreted (or WHENCE). The three WHENCE's are SEEK_SET (absolute position, or relative to file beginning), SEEK_CUR (relative to where I am right now), and SEEK_END (relative to the end of the file). seek might also be useful.

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      Thanks for the explanation. But I still get the same error, here is a small test script (called fio.pl):
      #! /usr/bin/perl use strict ; use File::Binary ; use Fcntl 'SEEK_SET'; my $fb = File::Binary->new("fio.pl"); $fb->seek(10, SEEK_SET ) ; $fb->close ;


      Luca
        That's because File::Binary's code is wrong. Specifically, the seek() method is written as so:
        sub seek { my $self = shift; my $seek = shift; unless ($self->{_is_seekable}) { carp "FH is not seekable" if $DEBUG; return 0; } $self->{_fh}->seek($seek) if defined $seek; $self->_init_bits(); return $self->{_fh}->tell(); }

        Which is wrong. The whole module is written rather sloppily, frankly. Which is not surprising, given that the test suite doesn't even have a test for seek().

        Furthermore, the test coverage for the 2874 tests is only

        ---------------------------- ------ ------ ------ ------ ------ ------ + ------ File stmt bran cond sub pod time + total ---------------------------- ------ ------ ------ ------ ------ ------ + ------ blib/lib/File/Binary.pm 79.2 47.6 37.5 87.1 95.0 100.0 + 73.1 Total 79.2 47.6 37.5 87.1 95.0 100.0 + 73.1 ---------------------------- ------ ------ ------ ------ ------ ------ + ------
        If I were you, I would find some other way to do what you're trying to do.

        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: File::Binary:howto goto a position in file
by jeanluca (Deacon) on Mar 12, 2006 at 14:11 UTC
    What about this approach:
    #! /usr/bin/perl use strict ; use Fcntl 'SEEK_SET'; use IO::Seekable; # not sure if this will help our @ISA = qw(IO::Seekable); open IN,"<fio.pl" ; binmode IN ; my $reclen = 1 ; my $binrec ; while ( read(IN, $binrec, $reclen) ) { print "".unpack("A",$binrec) ; } ....... # seek ?

    Can I apply a seek via this approach ?

    Luca
      Close. Either use the OO approach (by creating an IO::File) or the functional approach, but forget this whole @ISA = qw(IO::Seekable) business.
      #! /usr/bin/perl use strict; use warnings; use Fcntl 'SEEK_SET'; open local *IN, "<", "fio.pl" ; # XXX Check for errors binmode IN ; my $reclen = 1 ; my $binrec ; while ( read(IN, $binrec, $reclen) ) { print "".unpack("A",$binrec) ; # XXX What's with '"".'? } seek(IN, 10, SEEK_SET); # or whatever

      Docs: seek

        Thnx, I've fixed it (without OO). If I try OO, like:
        #! /usr/bin/perl use strict ; use Fcntl 'SEEK_SET'; use IO::File ; my $fh = new IO::File ; $fh->open("fio.pl") ; $fh->binmode() ; $fh->setpos(4) ; my $in ; $fh->read($in,2) ; printf "result: %s\n",unpack("A2",$in) ; $fh->close() ;
        The output is: result: #! (thats no shift at all!)
        But I get the idea that the biggest mistake has been made with the read command....
        Also, what about perldoc IO::Handler:
        $io->read ( BUF, LEN, [OFFSET] )
        I miss the explanation of the 3 variables BUF, LEN and OFFSET ?

        Thanks
        Luca

        update: solved the seek issue: $fh->seek(5, SEEK_SET) ;
        I guess the only thing I don't understand is the OFFSET. If I give that a number I get nothing... ?