如何使用Perl打开Unicode文件?

Jac*_*ius 10 unicode perl encoding file

我正在使用osql对数据库运行几个sql脚本,然后我需要查看结果文件以检查是否发生了任何错误.问题是Perl似乎不喜欢结果文件是Unicode的事实.

我写了一个小测试脚本来测试它,输出结果都出现了问题:

$file = shift;

open OUTPUT, $file or die "Can't open $file: $!\n";
while (<OUTPUT>) {
    print $_;
    if (/Invalid|invalid|Cannot|cannot/) {
        push(@invalids, $file);
        print "invalid file - $inputfile - schedule for retry\n";
        last;
    }            
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?我尝试使用解码,decode_utf8但它没有任何区别.我还尝试在打开文件时设置编码.

我认为问题可能是osql将结果文件放在UTF-16格式中,但我不确定.当我在textpad中打开文件时,它只是告诉我'Unicode'.

编辑:使用perl v5.8.8编辑:十六进制转储:

file name: Admin_CI.User.sql.results
mime type: 

0000-0010:  ff fe 31 00-3e 00 20 00-32 00 3e 00-20 00 4d 00  ..1.>... 2.>...M.
0000-0020:  73 00 67 00-20 00 31 00-35 00 30 00-30 00 37 00  s.g...1. 5.0.0.7.
0000-0030:  2c 00 20 00-4c 00 65 00-76 00 65 00-6c 00 20 00  ,...L.e. v.e.l...
0000-0032:  31 00                                            1.
Run Code Online (Sandbox Code Playgroud)

Sin*_*nür 16

该文件大概是UCS2-LE(或UTF-16格式).

C:\Temp> notepad test.txt

C:\Temp> xxd test.txt
0000000: fffe 5400 6800 6900 7300 2000 6900 7300  ..T.h.i.s. .i.s.
0000010: 2000 6100 2000 6600 6900 6c00 6500 2e00   .a. .f.i.l.e...

打开此类文件进行读取时,需要指定编码:

#!/usr/bin/perl

use strict; use warnings;

my ($infile) = @ARGV;

open my $in, '<:encoding(UCS-2le)', $infile
    or die "Cannot open '$infile': $!";
Run Code Online (Sandbox Code Playgroud)

请注意,fffe开头是BOM.


bri*_*foy 9

答案在open的文档中,也指向perluniintro.:)

open my $fh, '<:encoding(UTF-16LE)', $file or die ...;
Run Code Online (Sandbox Code Playgroud)

您可以获得perl支持的编码名称列表:

% perl -MEncode -le "print for Encode->encodings(':all')"
Run Code Online (Sandbox Code Playgroud)

之后,由您决定文件编码是什么.这与打开任何编码不同于默认值的文件的方式相同,无论是否由Unicode定义.

我们在Effective Perl Programming中有一章介绍了详细信息.


Eug*_*ash 5

尝试使用指定的IO层打开文件,例如:

open OUTPUT,  "<:encoding(UTF-8)", $file or die "Can't open $file: $!\n";
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅perldoc open.