我有一个包含字符串字段input
的类,其中包含UTF-8字符。我的班级也有一个方法toString
。我想使用方法toString
将类的实例保存到文件中。问题是文件中写有奇怪的符号:
my $dest = "output.txt";
print "\nBefore saving to file\n" . $message->toString() . "\n";
open (my $fh, '>>:encoding(UTF-8)', $dest)
or die "Cannot open $dest : $!";
lock($fh);
print $fh $message->toString();
unlock($fh);
close $fh;
第一次打印效果很好
Input: {"paramkey":"message","paramvalue":"здравейте"}
正在打印到控制台。问题是当我写文件时:
Input: {"paramkey":"message","paramvalue":"здÑавейÑе"}
我使用flock
来锁定/解锁文件。
答案 0 :(得分:1)
我想你错过了
use utf8;
在你的代码......
此代码生成您期望的“output.txt”文件:
#!/usr/bin/perl
use strict;
use utf8;
my $dest = "output.txt";
my $message = "здравейте";
print "\nBefore saving to file\n" . $message . "\n";
open (my $fh, '>>:encoding(UTF-8)', $dest)
or die "Cannot open $dest : $!";
lock($fh);
print $fh $message;
close $fh;
我没有使用toString()
方法,因为我正在处理原生字符串,而不是真正的对象,但这并没有改变实质内容......
答案 1 :(得分:1)
toString
方法返回的字符串内容已经过UTF-8编码。当你将它打印到你的终端时它工作正常,因为它期望UTF-8数据。但是当您使用
open (my $fh, '>>:encoding(UTF-8)', $dest) or die "Cannot open $dest : $!"
你要求Perl 重新编码数据为UTF-8。这会将UTF-8编码数据的每个字节转换为单独的UTF-8序列,这根本不是您想要的。很遗憾,您没有显示$message
所属的类的代码,因此我无法帮助您解决此问题
您可以通过将open
调用更改为
open (my $fh, '>>', $dest) or die "Cannot open $dest : $!"
这将避免额外的编码步骤。但是你应该在你的Perl代码中使用未编码的字符:从正在读取的文件中删除任何编码,并在写入输出文件时根据需要编码输出数据。
答案 2 :(得分:0)
您的toString
方法如何运作?我猜,根据你提供的输出,toString
方法产生的是字节而不是字符,然后perl在尝试转换它时会感到困惑。
在打印之前尝试binmode STDOUT, ':encoding(UTF-8)'
,看它是否与文件产生相同的输出 - 否则你的测试是苹果和橘子。
如果它已经是字节而不是字符,那么您可以打开$dest
而没有任何encoding(...)
图层,这样就可以了。
一般来说,我发现在字符中使用字符非常痛苦,但是由于它解决了我不再需要考虑的更多极端情况,额外的工作变得值得,但这是额外的工作。 / p>