【问题标题】:perl file to hex number 82?perl 文件到十六进制数 82?
【发布时间】:2019-06-09 12:53:09
【问题描述】:

尝试对文件进行二进制到十六进制的转换。我可以输出十六进制,但是当我尝试将结果输出到文件时,变量返回字符串“82”。我不明白为什么;就像所有的事情很可能是简单的一样。

#!/usr/bin/perl -w

use strict;

my $blockSize = 1024;
my $fileName = $ARGV[0];
my $hexName = $ARGV[1];
open(F,"<$fileName") or die("Unable to open file $fileName, $!");
binmode(F);
my $buf;
my $ct=0;

while(read(F,$buf,$blockSize,$ct*$blockSize)){
    foreach(split(//, $buf)){
    printf unpack ("H*", $_);    #prints the hex stream to terminal just fine
    open(H,">$hexName") or die("Unable to open file $fname, $!");
    binmode (H);
        printf H unpack ("H*", $_);
    close (H);

    }
    print "\n";
    $ct++;
}
close(F);

输出

perl rawrHexFile.pl test.png file.hex
89504e470d0a1a0a0000000....

mookie@temple:/srv/bench % cat file.hex 82

cat file.hex
82

谢谢。

这是我的最终代码。如果发生

use strict;
my $fileName = $ARGV[0];
my $hexName = $ARGV[1];
my $hexCodeFile = $ARGV[2];
my $hexDecodeFile = $ARGV[3];
my $blockSize = -s $fileName;
my $buf;

open(F,"<$fileName") or die("Unable to open file $fileName, $!");
binmode(F);

open(H,">$hexName") or die("Unable to open file $hexName, $!");
read(F,$buf,$blockSize);
        print H unpack ("H*", $buf);
close (H);
close(F);

【问题讨论】:

  • 首先,程序甚至没有编译,所以它没有给你你声称的输出。
  • 您为输入文件的每个字节重新创建文件 (open &gt;),因此您只获得输入文件最后一个字节的输出。在循环外打开文件
  • 许多其他问题(2-arg 打开,printf 没有模式,不必要地使用全局变量,当unpack H* 处理任何长度的字符串时不必要地拆分输入,1 KiB read当 Perl 从操作系统读取 4 KiB 或 8 KiB 块时,使用 binmode 作为文本文件)
  • 现在可以了。干杯! - 我已经交换了 blockSize 以使用“-s $fileName”来自动确定文件长度并与你的 cmets 一起整理。它现在可以将十六进制写入文件。谢谢。
  • 糟糕的解决方案。它引入了竞争条件和不必要的限制。按照我的建议移动open 是你应该做的。

标签: file perl hex


【解决方案1】:

您为输入文件的每个字节重新创建文件(打开>),因此您只获得输入文件的最后一个字节的输出。在循环外打开文件。

此外,您继续附加到 $buf 而不是替换其内容,因此您的输出将看起来像 AABABCABCDABCDE 而不是所需的 ABCDE(其中每个字母代表 1024 字节输入的输出)

固定:

use strict;
use warnings qw( all );

use constant BLOCK_SIZE => 64*1024;

my ($in_qfn, $out_qfn) = @ARGS;

open(my $in_fh, '<:raw', $in_qfn)
   or die("Unable to open \"$in_qfn\": $!\n");
open(my $out_fh, '>', $out_qfn)
   or die("Unable to open \"$out_qfn\": $!\n");

while (1) {
    defined( my $rv = sysread($in_fh, my $buf, BLOCK_SIZE) )
       or die("Unable to read from \"$in_qfn\": $!\n");

    last if !$rv;

    print($fh_out unpack("H*", $buf))
       or die("Unable to write to \"$out_qfn\": $!\n");
}

close($fh_in);
close($fh_out)
   or die("Unable to write to \"$out_qfn\": $!\n");

以上解决了您程序中的许多其他问题:

  • 使用 2-arg open
  • 不带模式使用 printf
  • 不必要地使用全局变量
  • unpack H* 处理任意长度的字符串时不必要地拆分输入
  • 当 Perl 从操作系统读取 4 KiB 或 8 KiB 块时,1 KiB 读取效率低
  • 对文本文件使用 binmode

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 1970-01-01
    • 2011-12-09
    • 2020-02-09
    • 2018-07-26
    • 2014-08-24
    • 1970-01-01
    相关资源
    最近更新 更多