Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Problem on substr record on binary file

by bh_perl (Monk)
on Jun 25, 2010 at 06:29 UTC ( #846467=perlquestion: print w/replies, xml ) Need Help??

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


hi

I have a binary file, the first bytes is represent the record type and the second byte represent the record length. Due to that, i have to read the second byte to get total record length and read the record base on the length.

sample data as below
84 47 00 0c 00 00 11 0a 03 50 35 04 00 64 0a 04 16 12 00 1e 00 1d 00 00 65 09 08 54 52 03 2f 82 05 10 00 02 6e 06 0b a8 53 11 67 00 00 00 7a 7f 00 69 4a 42 47 48 4a 41 0c 00 6a 53 54 4d 44 54 4f 1c 00 66 04 00 00

After i read the record length and substr the record. The substr result is not running properly. It was not substr the record based on the length. Why this is happened and below is the output of my program:
RECORD TAG : 84 RECORD LENGTH : 71 RECORD : 000c0000110a RECORD TAG : 03 RECORD LENGTH : 80 RECORD : 350400640a RECORD TAG : 04 RECORD LENGTH : 22 RECORD : 12001e001d00006509085452032f82051000026e060b RECORD TAG : 04 RECORD LENGTH : 22 RECORD : 120021001b00006509084480900f82051000046e0608 RECORD TAG : 03 RECORD LENGTH : 39

This is my code
#!/usr/bin/perl -w use Cwd; use warnings; use strict; use Getopt::Long; use constant FILEHDR => 4; use constant CDRLEN => 286; my ($trace, $help, $infile); my $swap = ''; my $indir = getcwd; my $outdir = getcwd; GetOptions ( "h|help" => \$help, "filename|f=s" => \$infile, "swap|s" => \$swap, "input|i=s" => \$indir, "output|o=s" => \$outdir, "trace|t" => \$trace ) or usage(); sub usage { exit; } my $outfile = $infile; my $data; if ($infile) { #open (OUTPUT, ">$outdir/$outfile"); open (DATA, "$indir/$infile"); binmode DATA; while ($data = <DATA>) { my $tag = unpack "H2", substr $data,0,1,''; my $length = unpack "C", substr $data,0,1,''; if ($length == 0x81) { $length = unpack "C", substr $data,0,1,''; } my $template = 'H' . $length*2; my $rec = unpack $template, substr $data,0,$length,''; printf ("RECORD TAG : %s\n", $tag); printf ("RECORD LENGTH : %s\n", $length); printf ("RECORD : %s\n", $rec); } close(DATA); #close(OUTPUT); }
Please help me..

Replies are listed 'Best First'.
Re: Problem on substr record on binary file
by moritz (Cardinal) on Jun 25, 2010 at 06:55 UTC
    while ($data = <DATA>) {

    reads data line by line. If your binary data contains a newline somewhere (which is the case in the first line of the hexdump output, the 0x0a), the record is split up into several lines, messing up the processing of the records.

    Instead you should use read to read the first two bytes, and then again read as many bytes as the second byte specifies.

    Perl 6 - links to (nearly) everything that is Perl 6.
    A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://846467]
Approved by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2023-02-06 20:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I prefer not to run the latest version of Perl because:







    Results (36 votes). Check out past polls.

    Notices?