无法使用Text::CSV_XS Perl模块写入UTF-16LE编码的CSV文件
我想写一个用UTF-16LE编码的CSV文件。 但是,文件中的输出会出错。有一些看起来很奇怪的中文字母:挀攀氀氀⸀㬀挀攀氀氀⸀㈀㬀ഀ. 这看起来像这里提到的一个字节的问题: 关于Perl和Text::CSVxs的其他线程没有帮助 我就是这样尝试的:无法使用Text::CSV_XS Perl模块写入UTF-16LE编码的CSV文件,perl,csv,encoding,Perl,Csv,Encoding,我想写一个用UTF-16LE编码的CSV文件。 但是,文件中的输出会出错。有一些看起来很奇怪的中文字母:挀攀氀氀⸀㬀挀攀氀氀⸀㈀㬀ഀ. 这看起来像这里提到的一个字节的问题: 关于Perl和Text::CSVxs的其他线程没有帮助 我就是这样尝试的: #!perl use strict; use warnings; use utf8; use Text::CSV_XS; binmode STDOUT, ":utf8"; my $csv = Text::CSV_XS->new({
#!perl
use strict;
use warnings;
use utf8;
use Text::CSV_XS;
binmode STDOUT, ":utf8";
my $csv = Text::CSV_XS->new({
binary => 1,
sep_char => ";",
quote_char => undef,
eol => $/,
});
open my $in, '<:encoding(UTF-16LE)', 'in.csv' or die "in.csv: $!";
open my $out, '>:encoding(UTF-16LE)', 'out.csv' or die "out.csv: $!";
while (my $row = $csv->getline($in)) {
$_ =~ s/ä/æ/ for @$row; # something will be done to the data...
$csv->print($out, $row);
}
close $in;
close $out;
结果如下所示:
header1;header2;挀攀氀氀⸀㬀挀攀氀氀⸀㈀㬀ഀ
æöü2.1;abc2.2;
它不是一个切换到UTF-8作为输出格式的选项(顺便说一句,它工作得很好)
那么,如何使用Text::CSV_XS编写有效的UTF-16LE编码的CSV文件呢?Perl在Windows上默认添加了
:crlf
。首先添加它,然后再添加:encoding
这意味着如果⇔CRLF转换将在读取解码之前和写入编码之后执行。这是倒退
它最终使用UTF-8,尽管是反向操作,因为满足以下所有条件:
- LF的UTF-8编码与其代码点(0A)相同
- CR的UTF-8编码与其代码点(0D)相同
- 0A始终引用LF,无论它们在文件中的何处
- 0D始终引用CR,无论它们在文件中的何处
open(我的$fh_输入’:原始:编码(UTF-16LE):crlf’,$qfn_输出)
Perl在Windows上默认添加了:crlf
。首先添加它,然后再添加:encoding
这意味着如果⇔CRLF转换将在读取解码之前和写入编码之后执行。这是倒退
它最终使用UTF-8,尽管是反向操作,因为满足以下所有条件:
- LF的UTF-8编码与其代码点(0A)相同
- CR的UTF-8编码与其代码点(0D)相同
- 0A始终引用LF,无论它们在文件中的何处
- 0D始终引用CR,无论它们在文件中的何处
open(我的$fh_输入’:原始:编码(UTF-16LE):crlf’,$qfn_输出)
您可以创建UTF8,然后使用Encode或Encode::Unicode将其转录到UTF-16LE吗?事实上,这是我考虑过的一种解决方法。文件内容不是UTF-16,另一个程序只需要UTF-16。但我不喜欢它,因为这是一个解决办法。我担心我遗漏了什么(琐碎的?),因为我假设Perl模块——特别是那些与IO有关的模块——应该能够处理UTF-16等。我不知道这个问题的答案:Text::CSV(而不是XS)能够处理UTF-16LE吗?XS模块没有处理另一个Unicode编码,这并不奇怪。我尝试了Text::CSV而不是Text::CSV_-XS,并使用$CSV->is_-pp进行了验证,但没有任何更改。输出仍然像XS模块一样混乱。您可以创建UTF8,然后使用Encode或Encode::Unicode将其转录到UTF-16LE吗?事实上,这是我考虑过的一种解决方法。文件内容不是UTF-16,另一个程序只需要UTF-16。但我不喜欢它,因为这是一个解决办法。我担心我遗漏了什么(琐碎的?),因为我假设Perl模块——特别是那些与IO有关的模块——应该能够处理UTF-16等。我不知道这个问题的答案:Text::CSV(而不是XS)能够处理UTF-16LE吗?XS模块没有处理另一个Unicode编码,这并不奇怪。我尝试了Text::CSV而不是Text::CSV_-XS,并使用$CSV->is_-pp进行了验证,但没有任何更改。输出仍然以与XS模块相同的方式混乱。对于那些刚刚发现这一点的人:使用上面的方法,但在使用模块的写入方法写入之前,首先将BOM添加到文件句柄,如打印$fh chr(0xFEFF)。一旦我这样做了,Excel就正确地显示了数据。是的,如果你想添加一个BOM表,你可以这样做(或者print$fh“\N{BOM}”;
),但这与手头的问题无关。没错,OP没有提到Excel,但我发现该程序的可读性是编写UTF16-LE csv文件的一个共同目标。对于那些刚刚发现这一点的人:在使用模块的写入方法编写之前,使用上面的方法,但首先向文件句柄添加BOM,如soprint$fh chr(0xFEFF)
。一旦我这样做了,Excel就正确地显示了数据。是的,如果你想添加一个BOM表,你可以这样做(或者print$fh“\N{BOM}”
),但这与手头的问题无关。没错,OP没有提到Excel,但我发现该程序的可读性是编写UTF16-LE csv文件的共同目标。
header1;header2;挀攀氀氀⸀㬀挀攀氀氀⸀㈀㬀ഀ
æöü2.1;abc2.2;
open(my $fh_in, '<:raw:encoding(UTF-16LE):crlf', $qfn_in)
open(my $fh_out, '>:raw:encoding(UTF-16LE):crlf', $qfn_out)