2010-05-22 1 views
7

나는 파일을 열 (직접 인코딩을 지정하는) 경우바이트 순서를 모르면 Perl에서 UTF-16 데이터를 어떻게 디코딩 할 수 있습니까?

open(my $file,"<:encoding(UTF-16)","some.file") || die "error $!\n"; 
while(<$file>) { 
    print "$_\n"; 
} 
close($file); 

내가 잘 파일 내용을 읽을 수 있습니다. 그러나, 내가 할 경우 :

use Encode; 

open(my $file,"some.file") || die "error $!\n"; 
while(<$file>) { 
    print decode("UTF-16",$_); 
} 
close($file); 

나는 다음과 같은 오류 얻을 :

UTF-16:Unrecognised BOM d at F:/Perl/lib/Encode.pm line 174 

가 어떻게 그것을 decode와 함께 작동 할 수 있습니까?

편집 :

FF FE 3C 00 68 00 74 00 
+1

는 당신이 우리 해당 파일의 처음 몇 바이트의 덤프 보여줄 수 : 당신은 당신이 디코딩 및 데이터의 다음 청크에 그것을 추가 할 수 없습니다 버퍼의 일부를 저장하는 Encode::FB_QUIET을 사용할 수 있나요? –

+1

아, 그럼 당신은 BOM을 가지고. –

답변

12

간단히 "UTF-16"을 지정하면 Perl은 바이트 순서 표시 (BOM)를 찾아 구문 분석하는 방법을 찾습니다. BOM이 없다면 폭발 할 것입니다. 이 경우 엔디안에 빅 엔디안에 대해 "UTF-16LE"또는 빅 엔디안에 "UTF-16BE"를 지정하여 바이트 순서를 인코딩해야합니다.

상황에 따라 다른 문제가 있지만 파일에있는 데이터를 보지 않고도 알기가 어렵습니다. 두 조각으로 같은 오류가 발생합니다. BOM이없고 바이트 순서를 지정하지 않으면 Perl이 어떤 방식 으로든 불평합니다. 어떤 Perl을 사용하고 있으며 어떤 플랫폼을 가지고 있습니까? 플랫폼에 파일의 기본 엔디안이 있습니까? 나는 내가 보는 행동이 문서에 따라 정확하다고 생각한다.

또한 알 수없는 인코딩 (Perl의 기본값이 무엇이든)으로 간단히 한 행을 읽을 수 없으며 그 행을 decode으로 보내십시오. 멀티 바이트 시퀀스의 중간에 오게 될 수도 있습니다.

open my($lefh), '<:raw', 'text-utf16.txt'; 

my $string; 
while($string .= <$lefh>) { 
    print decode("UTF-16LE", $string, Encode::FB_QUIET) 
    } 
+0

아시다시피 문자열을 하나의 큰 버퍼로 연결하면 성공적으로 디코드를 사용할 수 있습니다. – Geo

+3

전체 문자열에 대한 BOM을 볼 수 있기 때문에 전체 내용을 한 번에 해독 할 수 있습니다. 개별 라인으로 분해하면 BOM은 첫 번째 청크에만 해당됩니다. Encode는 한 문자열이 어떻게 든 다른 문자열과 관련되어 있다고 추측하려고 시도하는 데 특별한 조치를 취하지 않습니다. –

1

불가능한 것을 시도하십시오.

의 텍스트를 인코딩하지 않고 읽으므로 줄 바꿈 문자 (기본값은 \x0a)를 포함하는 모든 바이트가 한 줄을 끝냅니다. 그러나이 개행 문자는 UTF-16 문자 중간에있을 수 있습니다.이 경우 다음 행을 디코딩 할 수 없습니다. 데이터가 UTF-16LE 인 경우 항상 발생합니다. 줄 바꿈은 \x0a \x00입니다. UTF16-BE를 사용하는 경우 높은 바이트에 \x0a 문자가 생길 때까지 행운이 생길 수 있습니다 (줄 바꿈 문자는 \x00 \x0a).

따라서 올바른 인코딩으로 파일을 열지 마십시오.

+0

파일이 항상있는 것은 아니며 문자열 만 전달하면 어떻게됩니까? – Geo

+0

불가능하지는 않습니다 : 불완전한 바이트 시퀀스를 처리하는 방법에 대한 내 대답을보십시오. –

관련 문제