in reply to Reading binary file byte by byte

The implication of not expecting a logical record size other than 1 is that you don't want to be doing fixed length I/O in the first place. There is nothing wrong with doing ordinary variable length I/O even if there is no delimiter. Just set $/ to something likely to occur and process each string of bytes read in singly, e.g.
{ local $/ = chr(0); # if this occurs reasonably often in the file open (FILE, "file.binary"); while ( <FILE> ) { while ( length() ) { my $byte; ( $byte, $_ ) = /^(.)(.*)$/; ... Code here, processing $byte ... } } close FILE; }

One world, one people

Replies are listed 'Best First'.
Re^2: Reading binary file byte by byte
by ikegami (Patriarch) on Dec 21, 2010 at 18:02 UTC

    $/ is more flexible than you think.

    { open(my $FILE, "file.binary") or die $!; binmode($FILE); local $/ = \1; while ( my $byte = <$FILE> ) { ... } close $FILE; }

    But messing with global variables is messy. What if "..." calls a function that reads from a file? Just use read.

    { open(my $FILE, "file.binary") or die $!; binmode($FILE); while (read($FILE, my $byte, 1)) { ... } close $FILE; }
      Then we are back to reading a byte at a time from a file, which needs some thought applied first in terms of performance. It might be better than sysread which forces a system call with a 1 byte buffer, if thats what you request.

      Either way, if using buffered I/O, it seems more ept to read at least a page of memory in size at a time from the file but then process that one byte at a time.

      One world, one people

        read and readline (<>) are buffered, so it's not that bad. If you need Perl-side buffering, the following would be much better:
        use constant BLK_SIZE => 64*1024; { open(my $FILE, "file.binary") or die $!; binmode($FILE); while (read($FILE, my $buf, BLK_SIZE)) { for my $byte (unpack('a*', $buf)) { ... } } close $FILE; }
Re^2: Reading binary file byte by byte
by AnomalousMonk (Archbishop) on Dec 21, 2010 at 17:44 UTC

    Another way, using fixed-length I/O (and also avoiding use of a regex to step through the string byte-by-byte):

    >perl -wMstrict -le "{ local $/ = \10; my $fname = 'junk'; open my $fh, '<:raw', $fname or die qq{opening '$fname': $!}; while (defined(my $buffer = <$fh>)) { printf '%02x ', ord substr $buffer, $_, 1 for 0 .. length($buffer) - 1; print ''; } close $fh; } " 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 0d 0a

    Update: BTW: The test file was created with
        perl -e "print 'a' .. 'z', qq{\n}" > junk