确保我对utf8的处理是正确的

时间:2018-02-20 22:35:12

标签: perl

我正在使用Perl来处理涉及处理大量Unicode文档的模块。我开始变得紧张,因为我没有打开和关闭像open (OUT, '>:utf8', $textfile)这样的utf8图层的文件。但是,我已经进行了彻底的测试,输出仍然如预期。所以我想更好地了解原因。

简而言之,我的Perl模块将文档传递给外部服务并获得响应。答案将在Utf8中。它使用LWP :: UserAgent。当它获得响应时,它只是将其写入文件:

my $fh;
open($fh, '>', $outputpath) or die "Could not open file '$outputpath' $!";
print $fh $response->content;
close $fh;

我已将这些文件与代表"期望"的Unicode文件区分开来。输出,很好。然而,你可以在我的开放命令中看到我没有使用utf8层。那为什么呢?

如果我只是将$ response->内容返回到其他某个进程,而不是打印它,该怎么办?那么它仍然是合适的Unicode吗?

我还有一个单独的过程,我想问一下,非常相似的问题。在这种情况下,我正在尝试构建一个替换旧服务的新服务。旧版本从open(my $fh, '<:utf8', $inputfile)等文件中读取并写入新文件open(my $fh, '>:utf8', $outputfile)。新服务仍将以相同的方式读取,但不会再写入输出文件。它将使用HTTP将字符串发送到另一台服务器,并在该服务器上使用open(my $fh, '>', $outputfile)将其打印到文件中,因此不会使用utf8层。我无法立即更改该代码。

我希望文件内容与原本完全相同(其他处理规则都没有变化)。失去这一层我应该感到紧张吗?

我想如果我更好地理解这些层正在做什么,也许会有所帮助。

1 个答案:

答案 0 :(得分:3)

主要问题中没有“处理utf8 ”,这本身就不对。

整个过程都有效,因为服务器 按照你的说法发送utf8,按照以下方式。

content上使用的$response方法来自HTTP::Message

  

如果给出参数,content()方法设置原始内容。如果没有给出参数,则不触及内容。在任何一种情况下都会返回原始原始内容。

由于未在open中指定图层,因此使用默认值,对于Unix,可能为:unix:perlio,无编码(请参阅PerlIO)。所以你将原始字节转储到磁盘上,没有改变。

decoded_content( %options )处向下看页面,我们会看到默认

  

default_charset

     

这会覆盖由content_charset()猜测的默认字符集,或者如果失败“ISO-8859-1”。

并且可以通过打印来确定您获得的内容

say 'Content type: ', $response->content_charset;

你应该得到Content type: UTF-8。但是如果你从服务器接收到不同的编码,那么 会在文件中结束,任何期望utf8的代码都会中断。

应该始终解码所有输入并对所有输出进行编码。然后我们确切地知道发生了什么。当输入被解码时,程序继续使用字符串(不是发送任何编码的字节)。最后编码适合输出。这个EffectivePerler article应该是有用的。在这里,您将使用decoded_content并编写使用:encoding(UTF-8)打开的文件。

使用use open ":std", ":encoding(UTF-8)";,此pragma的词法范围内的所有I / O都将作为utf8处理。 (这可以覆盖其他特定用途,例如通过在三个参数中指定图层打开。) 请参阅open pragma

至于另一个问题,您需要正确编码您想要“发送到另一台服务器”的内容。怎么做取决于你如何“发送”它。

使用PerlIO可以设置I / O“层”,以便在读取或写入数据时根据需要在后台完成输入和输出的编码。这项工作由Encode完成。有关该过程的详细说明,请参阅Encode::PerlIO。 另请参阅perlunitutperlunifaqperluniitro