Perl:在读取文件的过程中更改编码的问题

时间:2011-03-14 23:00:06

标签: perl encoding binmode

我使用Perl加载一些'宏'文件。但是,这些宏可以用各种编码进行编码,因此为用户编写宏指定了一个指令(即

#encoding iso-8859-2

在宏的开头)。

每次在宏中遇到此指令时,都会调用函数设置编码,看起来像这样:

sub change_encoding {
  my ($file_handle, $encoding) = @_;
  $file_handle->flush();
  binmode($file_handle);           # get rid of IO layers
  binmode($file_handle,":encoding($encoding)");
}

问题是当我使用标准

读取宏时
while($line = <$file_handle>){
  process_macro($line);
}

我收到的消息是“utf8”\ xXY“不映射到Unicode”,但仅当带有变音符号的字符靠近#encoding指令时才会出现。我尝试了几个例子,我能够将一半的字符串与\ xXY代码和其他一半的字符串一起使用正确解码的字符,如下所示:

sub macro5_fn {
  print "\xBElu\xBBou\xE8k\xFD k\xF9\xF2 úpěl ďábelské ódy\n";
}

如果我在函数前添加了更多注释,则所有字符都可以:

sub macro5_fn {
  print "žluťoučký kůň úpěl ďábelské ódy\n";
}

简单地说,正确解码字符的数量取决于#encoding指令中这些字符的距离,关闭的字符不能正确解码。

在我看来,这是Perl和PerlIO(不)刷新缓冲区的问题。或者我做错了什么?

感谢您的回答。

1 个答案:

答案 0 :(得分:5)

问题是<>读取的不仅仅是一行,所以在您看到新的#encoding指令之前,在旧编码下解释下一行左右。

您最好的选择可能是以二进制模式读取文件并使用Encode模块解码当前编码中的每一行。