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

Dear Monks,

I have been re-directed from http://perlguru.com with regards to the following question. I have been attempting to write a code that reads a simple ASCII file and outputs it in a binary format. The problem comes that the outputted file is not in binary format (it is still in ASCII format, and this is backed up doing od -c filename).

I have tried using binmode <filehandle>, ":raw"; and also open (<fh>, ">:raw", $filename); but to no avail. Any suggestions as to what I am doing wrong? I enclose the rather primitive code at the bottom of this message.

Help regarding this matter would be very much appreciated. I have tried it on two separate versions of Linux, one based at home which is FC7 and the other is a version of CentOS. My hone version does have PerlIO.pm installed which makes it all the more perplexing. If you would like a copy of the input file, please let me know and I'll make it available.

Regards

Steve

#!/usr/bin/perl -w use strict; use vars qw/ $i $filename @line @splitdata @data $out /; $i=1649; #Obtain name of file printf ("Please enter the name of file which you would like converted\ +n"); chomp ($filename=<STDIN>); printf "Filename inputted was %s\n", $filename; #Open data file, rid the new lines and store it to the line array open ( DATAFILE, "<", "$filename"); chomp (@line = <DATAFILE>); close DATAFILE; #Read specific lines in while loop, split each part of each line, remo +ve whitespace via pop at the start and the end of the line and store +it to a new array called data while (defined($line[$i]) && $i < 3288){ @splitdata = split (/\s+/,$line[$i]); pop @splitdata; @splitdata =reverse(@splitdata); pop @splitdata; @splitdata =reverse(@splitdata); push @data, @splitdata; $i = $i + 1; } #Open an outfile and write the contents of data, in hexadecimal, into +a binary format open (OUTFILE, ">","newfile"); binmode OUTFILE, ":raw"; foreach $out (@data){ printf OUTFILE ("%08x\n", $out); } close OUTFILE;

Replies are listed 'Best First'.
Re: Woes with binmode
by pc88mxer (Vicar) on Mar 20, 2008 at 16:14 UTC
    This statement:
    printf OUTFILE ("%08x\n", $out);
    emits an 'ASCII' (text) representation of a number. I think you want something like:
    print OUTFILE pack('L', $out);
    which emits a more traditional 'binary' representation. See the documentation on pack for details on what formats for numbers are available.

    perl's binmode has nothing to do with how numbers are printed but with how perl converts characters to octet sequences (bytes). That said, you'll want to use binmode when printing data generated from pack since pack produces binary data and not text.

      Brilliant, this does the trick perfectly. I will have to consult the alpaca and see how the 'pack' function exactly works, but for the mean time my problem is solved.

      My sincere thanks for your help.

Re: Woes with binmode
by moritz (Cardinal) on Mar 20, 2008 at 14:45 UTC
    What do you mean by "binary"? Every ASCII file is also a binary file, but not the other ways round.

    So what exactly should the transformation do?

Re: Woes with binmode
by wade (Pilgrim) on Mar 20, 2008 at 16:14 UTC
    Yeah, you need to use 'binmode':
    if ( open (FILE, ">", "$filename") ) { binmode FILE; print FILE $webpage; close FILE; }
    OOPS: Sorry, I now see that you _are_ using binmode.
    --
    Wade