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

1 perl encoding binmode

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

#encoding iso-8859-2
Run Code Online (Sandbox Code Playgroud)

在宏的开头).

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

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

问题是当我使用标准读取宏时

while($line = <$file_handle>){
  process_macro($line);
}
Run Code Online (Sandbox Code Playgroud)

我收到消息说"utf8"\ xXY"没有映射到Unicode",但仅当带有变音符号的字符在#encoding指令附近时.我尝试了几个例子,我能够将一半的字符串与\ xXY代码和其他一半的字符串与正确解码的字符,如下所示:

sub macro5_fn {
  print "\xBElu\xBBou\xE8k\xFD k\xF9\xF2 úp?l ?ábelské ódy\n";
}
Run Code Online (Sandbox Code Playgroud)

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

sub macro5_fn {
  print "žlu?ou?ký k?? úp?l ?ábelské ódy\n";
}
Run Code Online (Sandbox Code Playgroud)

简单地说,正确解码的字符数取决于这些字符与#encoding指令的距离,那些接近的字符不能正确解码.

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

谢谢您的回答.

Ano*_*mie 5

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

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