我正在使用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层。我无法立即更改该代码。
我希望文件内容与原本完全相同(其他处理规则都没有变化)。失去这一层我应该感到紧张吗?
我想如果我更好地理解这些层正在做什么,也许会有所帮助。
答案 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。 另请参阅perlunitut,perlunifaq和perluniitro。