[英]How can I open a Unicode file with Perl?
我正在使用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;
}
}
有任何想法嗎? 我嘗試使用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.
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': $!";
請注意,開頭的fffe
是BOM 。
答案在open的文檔中,也指向perluniintro 。 :)
open my $fh, '<:encoding(UTF-16LE)', $file or die ...;
您可以獲得perl
支持的編碼名稱列表:
% perl -MEncode -le "print for Encode->encodings(':all')"
之后,由您決定文件編碼是什么。 這與打開任何編碼不同於默認值的文件的方式相同,無論是否由Unicode定義。
我們在Effective Perl Programming中有一章介紹了詳細信息。
嘗試使用指定的IO層打開文件,例如:
open OUTPUT, "<:encoding(UTF-8)", $file or die "Can't open $file: $!\n";
有關詳細信息,請參閱perldoc open 。
#
# -----------------------------------------------------------------------------
# Reads a file returns a sting , if second param is utf8 returns utf8 string
# usage:
# ( $ret , $msg , $str_file )
# = $objFileHandler->doReadFileReturnString ( $file , 'utf8' ) ;
# or
# ( $ret , $msg , $str_file )
# = $objFileHandler->doReadFileReturnString ( $file ) ;
# -----------------------------------------------------------------------------
sub doReadFileReturnString {
my $self = shift;
my $file = shift;
my $mode = shift ;
my $msg = {} ;
my $ret = 1 ;
my $s = q{} ;
$msg = " the file : $file does not exist !!!" ;
cluck ( $msg ) unless -e $file ;
$msg = " the file : $file is not actually a file !!!" ;
cluck ( $msg ) unless -f $file ;
$msg = " the file : $file is not readable !!!" ;
cluck ( $msg ) unless -r $file ;
$msg .= "can not read the file $file !!!";
return ( $ret , "$msg ::: $! !!!" , undef )
unless ((-e $file) && (-f $file) && (-r $file));
$msg = '' ;
$s = eval {
my $string = (); #slurp the file
{
local $/ = undef;
if ( defined ( $mode ) && $mode eq 'utf8' ) {
open FILE, "<:utf8", "$file "
or cluck("failed to open \$file $file : $!");
$string = <FILE> ;
die "did not find utf8 string in file: $file"
unless utf8::valid ( $string ) ;
}
else {
open FILE, "$file "
or cluck "failed to open \$file $file : $!" ;
$string = <FILE> ;
}
close FILE;
}
$string ;
};
if ( $@ ) {
$msg = $! . " " . $@ ;
$ret = 1 ;
$s = undef ;
} else {
$ret = 0 ; $msg = "ok for read file: $file" ;
}
return ( $ret , $msg , $s ) ;
}
#eof sub doReadFileReturnString
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.