Re: reading a few bytes into a file
- From: rob.dixon@xxxxxxx (Rob Dixon)
- Date: Wed, 30 Jul 2008 14:45:07 +0100
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,use strict;
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 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";
.
- Follow-Ups:
- Re: reading a few bytes into a file
- From: John W. Krahn
- Re: reading a few bytes into a file
- References:
- reading a few bytes into a file
- From: Scott Haneda
- Re: reading a few bytes into a file
- From: Rob Dixon
- reading a few bytes into a file
- Prev by Date: Re: reading a few bytes into a file
- Next by Date: Re: Regular expression: How to determine wether entry is a number?
- Previous by thread: Re: reading a few bytes into a file
- Next by thread: Re: reading a few bytes into a file
- Index(es):
Relevant Pages
|