为什么我的Perl程序使用Tie::File和Unicode/UTF-8编码失败?

为什么我的Perl程序使用Tie::File和Unicode/UTF-8编码失败?,perl,unicode,utf-8,tie,Perl,Unicode,Utf 8,Tie,我正在做一个用外语处理数据的项目。我的Perl脚本运行良好 然后我想使用Tie::File,因为这是一个简洁的概念(并且节省了时间和编码) 似乎Tie:File在Unicode/UTF-8下失败了(除非我遗漏了什么) 下面是一个描述问题的程序:(数据混合了英语、希腊语和希伯来语): 然后在标准输出上打印: 0 τι κάνετε; 1 πάρτε το ή αφήστε το 2 שלום חברים 3 abc לא כןכן efg 4 מתי ולאן This is it 5 מעכשי

我正在做一个用外语处理数据的项目。我的Perl脚本运行良好

然后我想使用Tie::File,因为这是一个简洁的概念(并且节省了时间和编码)

似乎Tie:File在Unicode/UTF-8下失败了(除非我遗漏了什么)

下面是一个描述问题的程序:(数据混合了英语、希腊语和希伯来语):

然后在标准输出上打印:

0 τι κάνετε;
1 πάρτε το ή αφήστε το
2 שלום חברים
3 abc לא כןכן efg
4 מתי ולאן This is it
5 מעכשיו לעכשיו
6 Σήμερα είναι Τρίτη
7 Θέλω να φάω
8 τι κάνετε;
9 שורה מס' 5
10
11
12
13
14 \xA4\xΘέλω\xA8\x

15
16
17
18

19
请注意,前10行是可以的,但是第10行到第19行不知从何而来!? 此外,绑定文件的输出包含损坏的数据:

 τι κάνϏN͏Ŏՠτήστε של חברءbc לؗܗࠗܗߠeמתולאן This is מעיו לעכ؎Ďώݎ֏ναι ΤρΘέώގѠφϏŎ٠κτε;שרה מס'



\xA4\xΘέλω\xA8\x
这里有点不对劲。要么我遗漏了什么,要么Tie:File无法处理Unicode/UTF-8? 我正在Windows7系统上运行草莓Perl 5.14

很多蒂亚-海伦


注意:我的建议在很大程度上取决于您试图解决的实际问题。孤立地看这个问题,我不会有太多的编码/解码“魔法”,只会使用原始字节(因为脚本不需要知道这个任务中字符本身的任何信息)。下面给出了您描述的输入和输出,生成了预期结果

use v5.014;
use warnings;
use autodie;

use Carp::Always;
use Tie::File;

my $file_in = 'test_in.txt';
my $file_out = 'test_tie.txt';

unlink $file_out;

tie my @tied, 'Tie::File', $file_out, recsep => "\x0D\x0A" or die 'tie failed';

open my $fh, '<', $file_in;
while (my $line = <$fh>) {
    chomp $line;
    push @tied, $line;
}
close $fh;

my $i = 0;
say $i++ . ' ' . $_ foreach @tied;

untie @tied;
使用v5.014;
使用警告;
使用自动模具;
经常使用;
使用Tie::文件;
my$file_in='test_in.txt';
my$file_out='test_tie.txt';
取消$file_的链接;
将我的@tie、'tie::File'、$File_out、recsep=>“\x0D\x0A”或“tie failed”绑定;

打开我的$fh,问题(可能最有可能)可能是您的数据一开始没有正确编码。这就是警告告诉你的。@Mat:数据编码正确。就像我上面说的,没有Tie::File,一切都很好。还要注意,STDOUT上的打印输出很好(前9行),您使用的是哪个编辑器,您确定它将源文件保存为UTF-8吗?(您不需要指定
使用功能qw;
,因为
使用v5.14;
可以启用该功能)@titanofold:I使用记事本++,以UTF8显式编码。(带或不带BOM-结果相同)。主要的问题不是警告:主要的问题是,当绑定文件处理UTF8时,Tie::file似乎会破坏数据(删除一些字符并添加其他字符)。谢谢,这很有启发性,我决定将其标记为已接受。尽管如此,正如remiah在这里建议的那样,我最终使用了与DB_文件和DBM_过滤器相关的tie:。那就行了。
 τι κάνϏN͏Ŏՠτήστε של חברءbc לؗܗࠗܗߠeמתולאן This is מעיו לעכ؎Ďώݎ֏ναι ΤρΘέώގѠφϏŎ٠κτε;שרה מס'



\xA4\xΘέλω\xA8\x
use v5.014;
use warnings;
use autodie;

use Carp::Always;
use Tie::File;

my $file_in = 'test_in.txt';
my $file_out = 'test_tie.txt';

unlink $file_out;

tie my @tied, 'Tie::File', $file_out, recsep => "\x0D\x0A" or die 'tie failed';

open my $fh, '<', $file_in;
while (my $line = <$fh>) {
    chomp $line;
    push @tied, $line;
}
close $fh;

my $i = 0;
say $i++ . ' ' . $_ foreach @tied;

untie @tied;