2015-01-06 2 views
3

У меня есть следующий блок в начале моего сценария:«Turn Off» binmode (STDOUT, «: utf8») Локально

#!/usr/bin/perl5 -w 
use strict; 
binmode(STDIN, ":utf8"); 
binmode(STDOUT, ":utf8"); 
binmode(STDERR, ":utf8"); 

В некоторых подпрограммах, когда есть другие кодировки (из далекой подпрограммы) , данные будут отображаться неправильно, при получении кириллических или других символов. Это «binmode», который вызывает проблему.

Могу ли я «отключить» binmode utf8 локально, только для подпрограммы?

Я не могу удалить глобальную настройку binmode, и я не могу изменить отдаленное кодирование.

+2

Назад. В случаях, когда вы выводите сочетание текста и байтов, не добавляйте ': utf8' в первую очередь. Кодируйте текст в байты вручную, чтобы вы только выводили байты. Гораздо проще. – ikegami

+0

Проблема в том, что я не могу удалить «: utf8», иначе это решило бы мою проблему. – DanielLazarov

+0

Несомненно, вы можете. Используйте клавишу delete для удаления операторов binmode. – ikegami

ответ

4

Одним из способов достижения этой цели является «DUP» STD ручку, установите дублированный дескриптор использовать :raw слой, и назначить его на локальную версию STD ручки. Например, следующий код

binmode(STDOUT, ':utf8'); 
print(join(', ', PerlIO::get_layers(STDOUT)), "\n"); 

{ 
    open(my $duped, '>&', STDOUT); 
    # The ':raw' argument could also be omitted. 
    binmode($duped, ':raw'); 
    local *STDOUT = $duped; 
    print(join(', ', PerlIO::get_layers(STDOUT)), "\n"); 
    close($duped); 
} 

print(join(', ', PerlIO::get_layers(STDOUT)), "\n"); 

отпечатки

unix, perlio, utf8 
unix, perlio 
unix, perlio, utf8 

на моей системе.

3

Мне нравится подход @ nwellnhof. Работа с Unicode и ASCII - это роскошь, которой пользуются немногие - мой инстинкт заключается в том, чтобы оставить байты как есть и выборочно использовать Encode до decode()/encode() при необходимости. Если вы можете определить, какой из ваших источников данных проблематичен, вы можете фильтровать/вставлять decode при работе с ними.

% file koi8r.txt 
koi8r.txt: ISO-8859 text 
% cat koi8r.txt 
������ �� ����� � ������� ���. ��� 
���� ����� ������ ����� �����. 
% perl -CO -MEncode="encode,decode" -E 'decode("koi8-r", <>) ;' koi8-r.txt 
Американские суда находятся в международных водах. Япония 
Смежные вопросы