2010-08-17 71 views
3

我試圖讀取與下面的代碼的二進制文件:使用ActivePerl讀取二進制文件的問題?

open(F, "<$file") || die "Can't read $file: $!\n"; 
binmode(F); 
$data = <F>; 
close F; 

open (D,">debug.txt"); 
binmode(D); 
print D $data; 
close D; 

輸入文件是16M; debug.txt只有大約400k。當我查看emacs中的debug.txt時,最後兩個字符是^ A^C(根據記事本++,SOH和ETX字符),儘管debug.txt中存在相同的模式。文件中的下一行確實有一個^ O(SI)字符,我認爲這是該特定字符的第一次出現。

我該如何閱讀整個文件?

+0

$ data = ;獲取$ data = do {undef $ /; }; – 2010-08-17 13:34:24

回答

5

如果你真的想要一次讀取整個文件,請使用slurp模式。可以通過將$/(這是輸入記錄分隔符)設置爲undef來開啓Slurp模式。這最好在一個單獨的塊中完成,因此您不要爲其他代碼搞砸$/

my $data; 
{ 
    open my $input_handle, '<', $file or die "Cannot open $file for reading: $!\n"; 
    binmode $input_handle; 
    local $/; 
    $data = <$input_handle>; 
    close $input_handle; 
} 

open $output_handle, '>', 'debug.txt' or die "Cannot open debug.txt for writing: $!\n"; 
binmode $output_handle; 
print {$output_handle} $data; 
close $output_handle; 

使用my $data爲一個全局變量詞法和our $data

+1

編輯爲了促進現代實踐,請參閱[爲什麼三個參數打開電話與詞法文件句柄Perl最佳實踐?](http://stackoverflow.com/questions/1479741/why-is-three-argument-開放調用與詞法文件句柄一個perl最佳實踐)和[什麼是在Perl中打開和讀取文件的最佳方式?](http://stackoverflow.com/questions/318789/whats-the -best路到開和讀取一個文件 - 在-perl的)。 – daxim 2010-08-17 13:53:10

+0

@daxim - 我想提出檢查,但我覺得這是O​​P自己的責任...... :) – MvanGeest 2010-08-17 13:53:57

+1

如果沒有領導好的榜樣和根除過時的代碼,我們不能教導。 :) – daxim 2010-08-17 14:06:46

3

TIMTOWTDI

File::Slurp是表達你想達到的最短的方式。它也有內置的錯誤檢查。

use File::Slurp qw(read_file write_file); 
my $data = read_file($file, binmode => ':raw'); 
write_file('debug.txt', {binmode => ':raw'}, $data); 

IO::File API更優雅時尚解決全局變量$/問題。

use IO::File qw(); 
my $data; 
{ 
    my $input_handle = IO::File->new($file, 'r') or die "could not open $file for reading: $!"; 
    $input_handle->binmode; 
    $input_handle->input_record_separator(undef); 
    $data = $input_handle->getline; 
} 
{ 
    my $output_handle = IO::File->new('debug.txt', 'w') or die "could not open debug.txt for writing: $!"; 
    $output_handle->binmode; 
    $output_handle->print($data); 
} 
+0

不要太在意高雅 - 這是一個快速&骯髒的解決方案。但感謝您的教育。 – chris 2010-08-17 14:24:19

+0

在第二個例子中,你爲什麼要將塊本地化? – jmcnamara 2010-09-17 12:05:35

+0

當句柄變量超出範圍時,附加的文件描述符會自動關閉。裸塊是創建這種範圍最直接的方法。 – daxim 2010-09-17 12:33:11

0

我不認爲這是關於使用slurp模式或不是,而是關於正確處理二進制文件。

代替

$data = <F>; 

你應該做的

read(F, $buffer, 1024); 

這將只讀取1024個字節,所以你必須增加緩衝或使用循環的一部分讀取整個文件的一部分。