in reply to how to search binary file

Read the full file in memory and use index() to search for the pattern:
#/!usr/bin/perl use warnings; use strict; @ARGV or die "usage: $0 file\n"; my $file = shift @ARGV; open my $fh, "<", $file or die "unable to open file"; binmode $fh; # disable "\n" translation my $data; { local $/=undef; $data=<$fh>; } my $pattern=pack('CC', 0xff, 0xd9); my $at=index($data, $pattern); if ($at<0) { print "pattern not found\n" } else { print "pattern found at pos $at\n" }

Replies are listed 'Best First'.
Re^2: how to search binary file
by Roy Johnson (Monsignor) on Apr 25, 2005 at 16:55 UTC
    No need to slurp the whole thing. Just set $/ to whatever you want to look for and see if it chomps.
    my $fi = "foo\xd9bar\xd9baz\xd9nothing"; open IN, '<', \$fi or die "Die fi!\n"; $/ = "\xd9"; while (<IN>) { print chomp() ? "Found after $_\n" : "Not after $_\n"; }

    Caution: Contents may have been coded under pressure.

      Of course, if the pattern is not found (or found late), your solution still slurps the whole file. The following solution keeps at most {buffer size}+{pattern length)-1 bytes of the file in memory at a time.

      my $pattern = "\xFF\xD9"; open(FILE, "< $file") or die("Unable to open input file: $!\n"); binmode(FILE); # Disable "\n" translation. $/ = \4096; # Arbitrary buffer size. my $block; my $partial = ''; my $base = 0; my $matches = 0; while ($block = <FILE>) { my $lookbehind = $partial . $block; my $pos = -1; for (;;) { $pos = index($lookbehind, $pattern, $offset+1); last if $pos == -1; print("Found a match at ", $base+$pos-length($partial), "\n"); $matches++; } $partial = substr($block, 1 - length($pattern)); $base += length($block); } if ($matches) { print("Found $matches matches.\n"); } else { print("Pattern not found.\n"); }

      Will report overlapping matches.

      Untested.