2009-09-02 8 views
3

의 내가Perl의 바이너리 파일에서 부호없는 int를 읽으려면 어떻게해야합니까?

[unsigned int(length of text)][text][unsigned int(length of text)][text][unsigned int(length of text)][text] 

같은 포맷 된 이진 파일 그리고 단지 반복 계속 파일에 대한 그 패턴이 있다고 가정 해 봅시다. 어떻게하면 서명되지 않은 int를 읽고 그것을 Perl의 텍스트 블록 다음에 인쇄합니까?

다시 말하지만이 파일은 일반 텍스트 파일이 아닌 바이너리 파일입니다.

답변

2

다음은 작은 작업 예제입니다.

#!/usr/bin/perl 

use strict; 
use warnings; 

my $INT_SIZE = 2; 
my $filename = 'somefile.bin'; 

open my $fh, '<', $filename or die "Couldn't open file $filename: $!\n"; 

binmode $fh; 

while (read $fh, my $packed_length, $INT_SIZE) { 

    my $text = ''; 
    my $length = unpack 'v', $packed_length; 

    read $fh, $text, $length; 

    print $length, "\t", $text, "\n"; 
} 

변경 INT_SIZE 및 압축 풀기 템플릿의 크기 및 엔디안 (중 'V'또는 'N'또는 'V'또는 'N') 이용할 수 있습니다. 자세한 내용은 unpack 맨 페이지를 참조하십시오.

1

데이터에 unpack 함수를 사용해야합니다. 체크 아웃 Pack/Unpack Tutorial (aka How the System Stores Data).

이것은 당신이 (32 비트를 가정) 올바른 방향으로 가고 얻을해야합니다

또한
#!/usr/bin/perl 

use strict; 

my $strBuf = "perl rocks"; 
my $packed = pack("I Z15", length($strBuf), $strBuf); 
{ 
    open(my $binFile, '>', "test.bin") || die("Error opening file\n"); 
    binmode $binFile; 
    print $binFile $packed; 
    close $binFile; 
} 


open(my $binFile, '<', "test.bin") || die("Error opening file\n"); 
binmode $binFile; 

my $buffer; 
read($binFile, $buffer, 4); ## Read out unsigned int binary data 
my $length = unpack("I", $buffer); ## Unpack the data 

read($binFile, $buffer, $length); ## Read the length out as binary 
my $string = unpack("Z$length", $buffer); ## Unpack the string data in buffer 

print "Len: $length String: $string\n"; 
exit; 
+1

당신의 코드는 C에서'unsigned int'가 4 바이트라고 가정합니다. (당신이 알고 있듯이) 대소 문자가 보장되지 않습니다. 이러한 혼란을 피하기위한 더 좋은 방법은 전체 파일을 읽고 _ 처리함으로써 코드가 'unsigned int'가 2 바이트 인 16 비트 플랫폼에서 실행되면 정상적으로 작동하도록하는 것입니다. –

+0

그것이 내가 32 비트라고 가정 한 이유입니다. 나는 메모리에 읽는 것이 좋고 논란의 여지가 있지만 더 좋은 해결책이라는 것에 동의하지만, 처리중인 파일의 크기 나 컴퓨터에서 사용할 수있는 메모리의 크기를 알지 못합니다. 두 솔루션 모두 pit-fall이 있습니다. –

+0

Chris, 메모리로 전체 파일을 읽는 것이 잘못된 정수 크기를 사용하지 않도록하려면 어떻게해야합니까? –

0

RC가 지적한대로, 당신은 거의 확실하게 데이터를 읽을 read 또는 sysread을 사용하는 것이 좋습니다, unpack를 사용하여 파일에서.

+0

에 대한 설명을 원합니다. –

0

이 문제를 완전히 해결하기에 충분한 정보가 없습니다.

길이 필드와 텍스트 필드의 정확한 형식이 필요합니다. int 2 바이트, 4 바이트 또는 8 바이트입니까? (모두 가능합니다.) 또한 little-endian 또는 big-endian입니까?

이 정보가 주어지면 read 함수를 사용하여 첫 번째 정수에 액세스 한 다음 비트 연산 또는 언팩 함수를 사용하여 숫자로 변환합니다.

다음 호는 텍스트 문자열의 정확한 형식입니다. ASCII, EBCDIC 또는 UTF 형식입니까? 이것을 알고 있으면 문자열의 길이를 계산할 수 있고 하나 이상의 읽기 연산을 사용하여 처리하기 쉬운 형식으로 변환해야 할 원시 문자열을 얻을 수 있습니다.

다른 한 가지 - 파일을 바이너리 모드로 열어야합니다. 그렇지 않으면 예상 결과를 얻지 못할 수 있습니다.

+0

플랫폼의 의존성에 의존 할 수 있도록 플랫폼의 기본'unsigned int'에'unpack' 코드가 있다고 가정합니다. 그리고 당신은 게으르면서 전체 파일을 읽은 다음, 일단 읽은 후에 처리를 할 수 있습니다. –

관련 문제