Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无法使用Text::CSV_XS Perl模块写入UTF-16LE编码的CSV文件_Perl_Csv_Encoding - Fatal编程技术网

无法使用Text::CSV_XS Perl模块写入UTF-16LE编码的CSV文件

无法使用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({

我想写一个用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({
    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,无论它们在文件中的何处
这些条件都不适用于UTF-16le

修正:

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,无论它们在文件中的何处
这些条件都不适用于UTF-16le

修正:

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,如so
print$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)