如何在Perl中读取二进制文件

Gra*_*ace 4 perl

我在编写Perl脚本来读取二进制文件时遇到问题.

我的代码如下所示,即$file二进制格式的文件.我试图通过网络搜索并在我的代码中应用,试图将其打印出来,但似乎它不能正常工作.

目前,它仅打印"&&&&&&&&&&&'和'’ppppppppppp’,但我真正想要的是它可以打印出各的$line,这样我以后可以做一些其他的后处理.另外,我不太清楚$data它是什么,因为我认为它是文章中的示例代码的一部分,说明是一个标量.我需要一个可以指出我代码中错误出错的人.以下是我的所作所为.

my $tmp = "$basedir/$key";
opendir (TEMP1, "$tmp");
my @dirs = readdir(TEMP1);
closedir(TEMP1);

foreach my $dirs (@dirs) {
    next if ($dirs eq "." || $dirs eq "..");
    print "---->$dirs\n";
    my $d = "$basedir/$key/$dirs";
    if (-d "$d") {
        opendir (TEMP2, $d) || die $!;
        my @files = readdir (TEMP2); # This should read binary files
        closedir (TEMP2);

        #my $buffer = "";
        #opendir (FILE, $d) || die $!;
        #binmode (FILE);
        #my @files =  readdir (FILE, $buffer, 169108570);
        #closedir (FILE);

        foreach my $file (@files) {
            next if ($file eq "." || $file eq "..");
            my $f = "$d/$file";
            print "==>$file\n";
            open FILE, $file || die $!;
            binmode FILE;
            foreach ($line = read (FILE, $data, 169108570)) {
                print "&&&&&&&&&&&$line\n";
                print "ppppppppppp$data\n";
            }
            close FILE;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经改变了我的代码,所以它如下所示.现在我可以阅读$ data了.感谢J-16 SDiZ指出这一点.我正在尝试将我从二进制文件中获取的信息推送到名为"@array"的数组,想要从数组中获取数据,以获取字符串中哪个匹配"p04"但是失败.有人可以指出错误在哪里?

my $tmp = "$basedir/$key";
opendir (TEMP1, "$tmp");
my @dirs = readdir (TEMP1);
closedir (TEMP1);

foreach my $dirs (@dirs) {
    next if ($dirs eq "." || $dirs eq "..");
    print "---->$dirs\n";
    my $d = "$basedir/$key/$dirs";
    if (-d "$d") {
        opendir (TEMP2, $d) || die $!;
        my @files = readdir (TEMP2); #This should read binary files
        closedir (TEMP2);

        foreach my $file (@files) {
            next if ($file eq "." || $file eq "..");
            my $f = "$d/$file";
            print "==>$file\n";
            open FILE, $file || die $!;
            binmode FILE;
            foreach ($line = read (FILE, $data, 169108570)) {
                print "&&&&&&&&&&&$line\n";
                print "ppppppppppp$data\n";
                push @array, $data;
            }
            close FILE;
        }
    }
}

foreach $item (@array) {
    #print "==>$item<==\n"; # It prints out content of binary file without the ==> and <== if I uncomment this.. weird!
    if ($item =~ /p04(.*)/) {
        print "=>$item<===============\n"; # It prints "=><===============" according to the number of binary file I have.  This is wrong that I aspect it to print the content of each binary file instead :(
        next if ($item !~ /^w+/);
        open (LOG, ">log") or die $!;
        #print LOG $item;
        close LOG;
    }
}
Run Code Online (Sandbox Code Playgroud)

同样,我改变了我的代码如下,但它仍然不起作用,因为它无法通过检查"日志"文件正确地grep"p04".它没有用grep整个文件包括像二进制这个"@ ^ @ ^ @ ^ @ ^ G ^ d ^ @ ^ @ ^ @ ^^ @ p04bbhi06 ^ @ ^ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @ ^ @hh ^ R ^ @ ^ @ ^ @ ^^ @ ^ @ ^ @ p04lohhj09 ^ @ ^ @ ^ @ ^^ @@".我所面对的是它只用grep p04bbhi06和p04lohhj09进行grep.以下是我的代码:

foreach my $file (@files) {
    next if ($file eq "." || $file eq "..");
    my $f = "$d/$file";
    print "==>$file\n";
    open FILE, $f || die $!;
    binmode FILE;
    my @lines = <FILE>;
    close FILE;
    foreach $cell (@lines) {
        if ($cell =~ /b12/) {
            push @array, $cell;
        }
    }
}

#my @matches = grep /p04/, @lines;
#foreach $item (@matches) {
foreach $item (@array) {
    #print "-->$item<--";
    open (LOG, ">log") or die $!;
    print LOG $item;
    close LOG;
}
Run Code Online (Sandbox Code Playgroud)

J-1*_*DiZ 7

使用:

$line = read (FILE, $data, 169108570);
Run Code Online (Sandbox Code Playgroud)

数据在$data; 并且$line是读取的字节数.

       my $f = "$d/$file" ;
       print "==>$file\n" ;
       open FILE, $file || die $! ;
Run Code Online (Sandbox Code Playgroud)

我想完整的路径是$f,但你正在打开$file.(在我的测试中 - 甚至$f不是完整的路径,但我想你可能还有其他的胶水代码...)

如果您只想浏览目录中的所有文件,请尝试File::DirWalkFile::Find.


Dim*_*oid 5

我不确定我是否理解你.

如果需要读取二进制文件,则可以执行与文本文件相同的操作:

open F, "/bin/bash";
my $file = do { local $/; <F> };
close F;
Run Code Online (Sandbox Code Playgroud)

在Windows下,您可能需要binmode F;在*nix下添加它没有它.

如果需要查找数组中哪些行包含某些单词,可以使用以下grep函数:

my @matches = grep /something/, @array_to_grep;
Run Code Online (Sandbox Code Playgroud)

您将获得新阵列中所有匹配的行@matches.

顺便说一句:我不认为一次将大量二进制文件读入内存是个好主意.你可以逐个搜索它们......

如果你需要找到其中的匹配时,你可以使用另一个标准函数,index:

my $offset = index('myword', $file);
Run Code Online (Sandbox Code Playgroud)