2009-12-27 59 views
1

我有兩個大小相等的二進制文件,但不是值。我使用unpack如下,但結果很奇怪。如何用Perl解壓二進制文件?

當我使用「大」的二進制文件,無論是輸出的顯示結果的一部分:

一個二進制文件開始好 - 壞的結束,

二二進制文件出錯的開始。

您認爲哪裏可能是弱點?

open(BIN_FILE1, "<bin_files/BINF1.bin") or die("Cannot open file for writing"); 
open(BIN_FILE2, "<bin_files/BINF2.bin") or die("Cannot open file for writing"); 
binmode(BIN_FILE1); 
binmode(BIN_FILE2); 
# N An unsigned long (32-bit) in "network" (big-endian) order. 
my @values_tmp1 = unpack("N*", <BIN_FILE1>); 
my @values_tmp2 = unpack("N*", <BIN_FILE2>); 
close (BIN_FILE1); 
close (BIN_FILE2); 
my $tmp_bin1 = @values_tmp1; 
my $tmp_bin2 = @values_tmp2; 
print "\nBIN FILE1 LENGTH: ",$tmp_bin1,"\n"; 
print "\nBIN FILE2 LENGTH: ",$tmp_bin2,"\n"; 

的輸出是:

BIN FILE1 LENGTH:1203

BIN FILE2 LENGTH:124個

輸入文件是:

-rw-rw-r-- 1 yodar yodar 9600 2009-12-23 19:59 BINF1.bin 
-rw-rw-r-- 1 yodar yodar 9600 2009-12-27 16:38 BINF2.bin 

如果有 另一種簡單而安全的方式來收集二進制文件數據到一個數組我很高興知道。

回答

9

我懷疑你沒有讀整個文件(<>操作員試圖使用記錄分隔符$ /,默認是換行符)來讀取記錄。嘗試改變閱讀是這樣的:

{ 
    # Enable slurp mode 
    local $/; 
    my @values_tmp1 = unpack("N*", <BIN_FILE1>); 
    my @values_tmp2 = unpack("N*", <BIN_FILE2>); 
} 
+0

是的,解決了這個問題。感謝Hastukun。 – YoDar

6

你說你有「大」的文件。看起來他們並不是那麼大,並且很容易適應記憶。

但是,如果您的文件太大而無法一次裝入內存,則可以使用readsysread來讀取塊中的數據。

示例 - 閱讀4000個字節在一個時間:

my $file_path = 'bin_files/BINF1.bin'; 

open my $fh, '<:encoding(raw)', $file_path 
    or die "Cannot open file '$file_path' for reading"; 

my $buffer; 
while (my $got = read($fh, $buffer, 4000)) { 

    warn "Read $got bytes from file\n." 

    my @integers = unpack "N*", $buffer; 

    do_stuff(\@integers); 

    $buffer = ''; 
} 

使用3參數open與詞彙手柄,它避免了一定的安全性和可維護性的問題。 3 arg open還允許您在模式標誌中指定文件編碼。這樣你就不需要調用binmode。