2010-08-17 7 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 = ; gets $ data = do {undef $ /; }; –

답변

5

정말로이라면 전체 파일을 한꺼번에 읽으려고합니다. 슬러 프 모드를 사용하십시오. Slurry 모드는 $/ (입력 레코드 분리 기호)을 undef으로 설정하여 켤 수 있습니다. 이것은 다른 블록에서 $/을 망치지 않도록 별도의 블록에서 수행하는 것이 가장 좋습니다.

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; 

글로벌 변수에 대한 어휘와 our $data에 대한 사용 my $data.

+1

현대 연습을 촉진하기 위해 편집 된 이유에 대해 [왜 어휘 파일 핸들을 사용하는 세 가지 인자의 공개 호출이 펄의 모범 사례입니까?] (http://stackoverflow.com/questions/1479741/why-is-three-argument- lexical-filehandles-perl-best-practice) 및 [Perl에서 파일을 열고 읽는 가장 좋은 방법은 무엇입니까?] (http://stackoverflow.com/questions/318789/whats-the -best-way-to-open-and-a-file-in-perl)을 지원합니다. – daxim

+0

@ daxim - 수표를 제안하고 싶었지만 OP 자신의 책임이라고 느꼈습니다. :) – MvanGeest

+1

좋은 역할 모델로 이끌고 오래된 코드를 없애지 않으면 가르 칠 수 없습니다. :) – daxim

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

+0

두 번째 예제에서 왜 코드를 블록 단위로 지역화합니까? – jmcnamara

+0

핸들 변수가 범위를 벗어나면 첨부 된 파일 설명자가 자동으로 닫힙니다. 적나라한 블록은 그러한 범위를 만드는 가장 직접적인 방법입니다. – daxim

0

슬러 프 모드 사용 여부는 아니지만 올바르게 바이너리 파일을 처리하는 것에 관한 것입니다. 당신이 버퍼를 증가 시키거나 루프를 사용하는 부분으로 전체 파일 부분을 읽을 그래서

대신

$data = <F>; 

당신은,이 내용은 1024 바이트를 읽

read(F, $buffer, 1024); 

해야한다.