首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >本地“关闭”binmode(STDOUT,“:utf8 8”)

本地“关闭”binmode(STDOUT,“:utf8 8”)
EN

Stack Overflow用户
提问于 2015-01-06 15:15:22
回答 3查看 1.7K关注 0票数 4

我的脚本开头有以下块:

代码语言:javascript
复制
#!/usr/bin/perl5 -w
use strict;
binmode(STDIN, ":utf8");
binmode(STDOUT, ":utf8");
binmode(STDERR, ":utf8");

在某些子程序中,当有其他编码(来自遥远的子例程)时,当接收到西里尔字母或其他字符时,数据将不能正确显示。造成问题的是“绑定模式”。

我可以在本地“关闭”绑定模式utf8,只用于子例程吗?

我无法删除全局二进制模式设置,也无法更改远程编码。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-01-06 15:49:03

实现这一目标的一种方法是"dup“STD句柄,将重复的文件句柄设置为使用:raw层,并将其分配给STD句柄的本地版本。例如,下面的代码

代码语言:javascript
复制
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");

版画

代码语言:javascript
复制
unix, perlio, utf8
unix, perlio
unix, perlio, utf8

在我的系统里。

票数 7
EN

Stack Overflow用户

发布于 2015-01-06 18:43:04

我喜欢@nwellnhof的方法。只处理Unicode和ASCII --这是很少人喜欢的奢侈品--我的本能反应是保留原样的字节,并在需要时选择性地使用Encodedecode()/encode()。如果您能够确定哪些数据源是有问题的,则可以在处理这些数据源时筛选/插入decode

代码语言:javascript
复制
% file koi8r.txt 
koi8r.txt: ISO-8859 text
% cat koi8r.txt 
������ �� ����� � ������� ���. ���
���� ����� ������ ����� �����.
% perl -CO -MEncode="encode,decode" -E 'say decode("koi8-r", <>) ;' koi8r.txt
Американские суда находятся в международных водах. Япония
票数 3
EN

Stack Overflow用户

发布于 2019-08-08 09:25:23

您可以使用类似于经营范围:保护范围内的资源管理的东西来确保在离开作用域时将其设置为:utf8,而不管如何(返回、死亡、任何方式):

代码语言:javascript
复制
#!/usr/bin/perl -w
use strict;

use Scope::Guard qw(guard);

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

{
    # When guard goes out of scope, this sub is guaranteed to be called:
    my $guard = guard {
        binmode(STDOUT, ':utf8');
    };
    binmode(STDOUT, ':raw');
    print(join(', ', PerlIO::get_layers(STDOUT)), "\n");
}

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

或者,如果您不想包含一个新的依赖关系,比如作用域::卫士(作用域::卫士是这种本地化.)的最佳选择:

代码语言:javascript
复制
#!/usr/bin/perl -w
use strict;

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

{
    my $guard = PoorMansGuard->new(sub {
        binmode(STDOUT, ':utf8');
    });
    binmode(STDOUT, ':raw');
    print(join(', ', PerlIO::get_layers(STDOUT)), "\n");
}

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

package PoorMansGuard;

sub new {
    my ($class, $sub) = @_;
    bless { sub => $sub }, $class;
}

sub DESTROY {
    my ($self) = @_;
    $self->{sub}->();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27801561

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档