Scott Haneda wrote: > > Hi Rob, thanks for your reply. This is my first adventure into perl, > and I am a bit stumped. I have experience in a few web scripting > languages, but this is a little new to me. > > Your script does work, and returns a number, but not the correct one, > and I think it has to do with my in file being in a strange format. > It is a email Inbox, the message count is told to me by the developer > to be 4 bytes in, 4 bytes long, and a big endian value. I just want > the mailbox count of messages out of it, which the C code below did in > fact do. I just have issues moving that C binary to other machines, > and perl will be more universal. > > I zipped a file and put it up, it should have 8 messages in it. The > developer of the email server is not as forthcoming with help in this > regard, so I am at a loss for a lot of data on the format of the file. > > There is a sample file here: > http://www.newgeo.com/web/misc/62315-testbox.zip > > If you would not mind taking a look at it, I will post a follow up to > the list explaining how it all works, as soon as I understand it. > > I put a few comments inline below about your code. > >>> Hello, I have this small C app that someone wrote for me ages ago, >>> and >>> am tired of it breaking every time I move it around to various >>> systems, I will include it below. >>> >>> I am hoping I can do this in perl, as a one liner, were it will >>> read a >>> the first 4 bytes of a file, grab 4 bytes out of the file, which is a >>> big endian value, and return that as an int to me. >>> >>> Here is the basic C app I have been using: >>> >>> #include <stdio.h> >>> #include <libkern/OSByteOrder.h> >>> >>> int main (int argc, char *argv[]) { >>> FILE* fd; >>> char buffer[8]; >>> unsigned long int dv; >>> >>> //open the file >>> fd = fopen(argv[1], "r"); >>> printf("Filename: %-50s", argv[1]); >>> >>> fread(buffer, 1, sizeof(buffer), fd); >>> dv = OSReadBigInt32(buffer, 4); >>> >>> // print the decimal value >>> printf(" Value: %ld\n", dv); >>> >>> return 0; >>> } >> use strict; >> use warnings; >> >> my $file = shift; >> >> open my $fh, '<', $file or die $!; >> print "Filename: $file"; > > Is there no need to close the file handle? If not, what harm is there > in leaving it open? > >> my $buffer; >> my $count = read $fh, $buffer, 4 or die $!; >> die "Insufficient data in file" unless $count >= 4; >> >> my $dv = unpack 'N', $buffer; >> print " Value: $dv\n"; > > I just read the docs on unpack, and I do not follow what the purpose > is here?
OK, first of all the correction. I didn't know the function of OSReadBigInt32 and assumed the second parameter was a byte count. It seems that it's actually a byte offfset, so we need to read in eight bytes to start with and convert the last four to a big-endian longword. Version 0.2 is below and I hope it gives you the right value this time. Now for the questions. - Using a lexical scalar file handle conveniently closes the file when the scalar goes out of scope. In this case it will be closed at the end of the program, but it's a good habit to get into to restrict file operations to a small scope and rely on automatic closure. Something like this, for example my $first_line; { open my $fh, '<', $infile or die $!; $first_line = <$fh>; } which will open the file, read the first line and close it, leaving only the required data still existing. - The bulk of the documentation on 'unpack' is in perldoc -f pack and the new unpack format moves to a character offset of 4 (@4) and extracts a 32-bit big-endian integer (N). Finally, please post to the group and not directly to me, so that others can both help and be helped by the dialogue. Thanks. HTH, Rob use strict; use warnings; my $file = shift; open my $fh, '<', $file or die $!; print "Filename: $file"; my $buffer; my $count = read $fh, $buffer, 8 or die $!; die "Insufficient data in file" unless $count >= 8; my $dv = unpack '@4 N', $buffer; print " Value: $dv\n"; -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/