2013-03-28 3 views
0

펄에서 XML 파일의 일부 데이터를 처리 중이며 FIFO File :: Queue를 사용하여 프로세스를 분할하고 속도를 높이고 싶습니다. 한 펄 스크립트는 XML 파일을 구문 분석하고 다른 스크립트 JSON 출력을 준비 :File :: Queue가 perl에서 utf8 문자열을 처리 할 수있게 하시겠습니까?

#!/usr/bin/perl -w 
binmode STDOUT, ":utf8"; 
use utf8; 
use strict; 
use XML::Rules; 
use JSON; 
use File::Queue; 

#do the XML magic: %data contains result 

my $q = new File::Queue (File => './importqueue', Mode => 0666); 
my $json = new JSON; 
my $qItem = $json->allow_nonref->encode(\%data); 
$q->enq($qItem); 

만큼 %data 숫자 포함하고 A-Z 데이터 만이 잘 작동합니다. widechars 중 하나가 (. 예를 들어, L, A, S, Z 등)가 발생하지만 내가 받고 있어요 : Wide character in syswrite at /usr/lib/perl/5.10/IO/Handle.pm line 207.

나는 문자열이 유효한 UTF8인지 확인하는 것을 시도했다 :

print utf8::is_utf8($qItem). ':' . utf8::valid($qItem) 

및 나는 1:1을 얻었습니다 - 그래서 나는 정확한 utf8 문자열을 가지고 있습니다.

필자는 syswrite가 filehandler를 utf8로 인코딩 된 파일인지 알 수없는 대기열 파일로 가져올 수 있다는 것을 알았습니다.

맞습니까? 그렇다면 File : Queue가 : utf8 파일 핸들러를 사용하도록 강제하는 방법이 있습니까? 아마도 File : Queue가 최선의 선택이 아닙니다. 두 개의 perl 스크립트 사이에서 FIFO 대기열을 만들려면 sth else를 사용해야합니까?

답변

3

utf8::is_utf8은 문자열이 UTF-8을 사용하여 인코딩되었는지 여부를 알려주지 않습니다. (이 정보도 사용할 수 없습니다.)

>perl -MEncode -E"say utf8::is_utf8(encode_utf8(chr(0xE9))) || 0" 
0 

utf8::valid

이 문자열이 유효한 UTF-8인지 아닌지 여부를 알려하지 않습니다.

>perl -MEncode -E"say utf8::valid(qq{\xE9}) || 0" 
1 

둘 다 일부 내부 저장 세부 정보를 확인합니다. 둘 중 어느 것도 필요하지 않아야합니다.


File :: Queue는 바이트 문자열 만 전송할 수 있습니다. 문자열로 전송할 데이터를 직렬화하는 것은 사용자의 몫입니다.

텍스트를 직렬화하는 주요 수단은 문자 인코딩이거나 줄여서 인코딩입니다. UTF-8은 문자 인코딩입니다. 예를 들어

,

dostępu 

은 다음과 문자로 구성된 문자열 (각 유니 코드 코드 포인트) : '

64 6F 73 74 119 70 75 

모든 그 문자의 바이트에 맞지 때문에 문자열 수 File :: Queue를 사용하여 보내야합니다. 당신이 UTF-8을 사용하여 해당 문자열을 인코딩한다면, 다음과 같은 문자로 구성된 문자열을 얻을 것 : 해당 문자열이 :: 대기열 파일을 사용하여 전송 될 수 있도록

64 6F 73 74 C4 99 70 75 

그 문자는 바이트에 맞게.


JSON은 사용하는대로 유니 코드 코드 포인트의 문자열을 반환합니다. 따라서 문자 인코딩을 적용해야합니다.

File :: Queue는 자동으로 문자열을 인코딩하는 옵션을 제공하지 않으므로 직접 처리해야합니다.

당신은 인코딩 모듈

my $json = JSON->new->allow_nonref; 
$q->enq(encode_utf8($json->encode(\%data))); 
my $data = $json->decode(decode_utf8($q->deq())); 

에서 encode_utf8decode_utf8를 사용할 수 있습니다 또는 당신은 JSON 당신을 위해 디코딩/인코딩을 수행하도록 할 수 있습니다. 워드 프로세서 보면

my $json = JSON->new->utf8->allow_nonref; 
$q->enq($json->encode(\%data)); 
my $data = $json->decode($q->deq()); 
+0

감사 clariffication에 많은 도움이 될 프로그램의 상단에 use open OUT=> ':utf8'를 추가 추측에는 요. JSON 내부 utf8 인코딩'JSON-> new-> utf8-> allow_nonref;'내 하루 ;-) – TomekK

0

.....

perldoc -f syswrite 
       WARNING: If the filehandle is marked ":utf8", Unicode 
       characters encoded in UTF-8 are written instead of bytes, and 
       the LENGTH, OFFSET, and return value of syswrite() are in 
       (UTF8-encoded Unicode) characters. The ":encoding(...)" layer 
       implicitly introduces the ":utf8" layer. Alternately, if the 
       handle is not marked with an encoding but you attempt to write 
       characters with code points over 255, raises an exception. See 
       "binmode", "open", and the "open" pragma, open. 

man 3perl open 
use open OUT => ':utf8'; 
... 
with the "OUT" subpragma you can declare the default 
     layers of output streams. With the "IO" subpragma you can control 
     both input and output streams simultaneously. 

그래서 나는

+0

'use open'의 효과는 어휘 적으로 범위가 지정됩니다. File/Queue.pm 자체에 추가하지 않으면 도움이되지 않습니다. – ikegami

+0

@ikegami''binmode $ q -> {queue} ': utf8''' 그럼 어때요? :) – Vorsprung

+0

잘 작동 할 수도 있지만 모듈을 검토해야합니다. 확실히 안전한 방법은 아닙니다. – ikegami