如何使用Perl将指定格式的数据写入二进制文件?

时间:2010-08-19 13:39:56

标签: perl file-io binary hex

这可能是一个相当新手的问题,但我需要处理某个文本文件并将其内容转储到二进制文件中,我不知道如何 - 我决定使用perl,但我的perl技能非常低。我可能应该用C ++编写这个,但对于perl来说这似乎是一个很好的简单任务,所以为什么不学习新的东西呢? ;)文本文件有以下格式的数千行:

2A02FC42 4

您可以将其视为十六进制数字(长度始终 8)和常规数字。现在我需要以这种格式将所有行转储到二进制文件中(当使用十六进制编辑器查看时,它应该如下所示):

42FC022A00000004

更多例子很清楚:

70726F67 36 - > 676F727000000024
6A656374 471 - > 7463656A000001D7

解析输入文件的部分很简单,但我仍然停留在第二部分,我应该将其写入二进制文件。我不知道如何以这种方式格式化数据,甚至不知道如何以二进制模式输出数据。有人可以帮助我吗?

感谢。

编辑:更新了示例,忘记了endiannes - 我在LE系统上。

3 个答案:

答案 0 :(得分:6)

使用pack

#! /usr/bin/perl

use warnings;
use strict;

# demo only    
*ARGV = *DATA;

while (<>) {
  my($a,$b) = split;
  $a = join "", reverse $a =~ /(..)/g;
  $b = sprintf "%08x", $b;

  print pack "H*" => $a . $b;
}

__DATA__
2A02FC42 4
70726F67 36
6A656374 471

示例运行:

$ ./prog.pl | od -t x1
0000000 42 fc 02 2a 00 00 00 04 67 6f 72 70 00 00 00 24
0000020 74 63 65 6a 00 00 01 d7
0000030

答案 1 :(得分:1)

我的版本(已测试):

my $fout;
if ( ! open( $fout, ">/tmp/deleteme.bin" ) ) {
    die( "Failed to open /tmp/deleteme.bin: $!" );
}
binmode( $fout );

while ( <DATA> ) {
    my ( $left, $right ) = split( /\s+/s, $_ );

    my $output = pack( "VN", hex($left), int($right) );
    printf(
        STDERR
        "  note, %8X %d -> " . ( "%02X" x 8 ) . "\n",
        hex($left), $right,
        map { $_ } unpack( "C8", $output )
    );

    print( $fout $output );
}
close( $fout );

__DATA__
70726F67 36 -> 676F727000000024
6A656374 471 -> 7463656A000001D7

输出:

note, 70726F67 36 -> 676F727000000024
note, 6A656374 471 -> 7463656A000001D7

答案 2 :(得分:0)

规范方法是使用pack。假设您从文本文件中读取的数据已经转换为数字(包括十六进制数据),并存储在变量$x$y中。那你应该做点什么

 print OUTFILE pack("NN", $x, $y);

如果您需要不同的字节顺序,则必须使用 来自NN的不同模板,有关详细信息,请参阅perldoc -f pack