如何从Perl中的二进制文件读取unsigned int?

ikfrs5lh  于 2022-11-15  发布在  Perl
关注(0)|答案(4)|浏览(179)

假设我有一个二进制文件,格式如下

[unsigned int(length of text)][text][unsigned int(length of text)][text][unsigned int(length of text)][text]

文件的模式一直在重复,我如何读取unsigned int并打印出来,然后在Perl中打印文本块?
同样,这是一个二进制文件,而不是纯文本文件。

z18hc3ub

z18hc3ub1#

下面是一个小的工作示例。

#!/usr/bin/perl

use strict;
use warnings;

my $INT_SIZE = 2;
my $filename = 'somefile.bin';

open my $fh, '<', $filename or die "Couldn't open file $filename: $!\n";

binmode $fh;

while ( read $fh, my $packed_length, $INT_SIZE ) {

    my $text = '';
    my $length = unpack 'v', $packed_length;

    read $fh, $text, $length;

    print $length, "\t", $text, "\n";
}

更改INT_SIZE以及解包模板的大小和字节序以适合('v'或'n'或'V'或'N')。有关详细信息,请参阅unpack联机帮助页。

ttcibm8c

ttcibm8c2#

您需要对数据使用unpack函数。请查看 Pack/Unpack Tutorial (aka How the System Stores Data)
这将使您朝着正确的方向前进(假设为32位):

#!/usr/bin/perl

use strict;

my $strBuf = "perl rocks";
my $packed = pack("I Z15", length($strBuf), $strBuf);
{
    open(my $binFile, '>', "test.bin") || die("Error opening file\n");
    binmode $binFile;
    print $binFile $packed;
    close $binFile;
}

open(my $binFile, '<', "test.bin") || die("Error opening file\n");
binmode $binFile;

my $buffer;
read($binFile, $buffer, 4);  ## Read out unsigned int binary data
my $length    = unpack("I", $buffer);  ## Unpack the data

read($binFile, $buffer, $length);  ## Read the length out as binary
my $string = unpack("Z$length", $buffer);   ## Unpack the string data in buffer

print "Len: $length  String: $string\n";
exit;
0yg35tkg

0yg35tkg3#

这里没有真正足够的信息来完全解决这个问题。
需要的是长度字段和文本字段的确切格式。int是2个字节、4个字节还是8个字节?(都有可能。)还有它是little-endian还是big-endian?
给定这些信息,然后使用read函数访问第一个整数,并使用位操作或unpack函数将其转换为数字。
下一个问题是文本字符串的确切格式。它是ASCII、EBCDIC还是UTF格式?了解了这些,您就可以计算字符串的长度,并使用一个或多个读取操作来获得原始字符串,然后将其转换为更易于管理的格式。
还有一件事--您需要以二进制模式打开文件,否则可能无法获得预期的结果。

rekjcdws

rekjcdws4#

除了使用unpack之外,正如RC指出的,您几乎肯定希望使用readsysread从文件中读取数据。

相关问题