2015-01-06 24 views
3

我在腳本的開始下列塊:「關閉」 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

當然可以。使用刪除鍵刪除binmode語句 – ikegami

回答

4

實現此目的的一種方法是「複製」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 - 一些奢侈品享受 - 我的直覺是將字節保持不變,並在需要時有選擇地使用Encodedecode()/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 
Американские суда находятся в международных водах. Япония