【问题标题】:Perl and Postgresql UTF8 problems with directoriesPerl 和 Postgresql UTF8 目录问题
【发布时间】:2016-03-24 09:02:28
【问题描述】:

我在使用 Perl 5.22 和 Postgresql (9.4) 的 Mac (10.11.2) 上遇到目录名称中包含 UTF8 字符的问题。 Postgresql 中的文本编码设置为 UTF8。

如果我有一个包含非 ascii UTF8 字符的目录名,如果目录名被 Perl 脚本读入或插入到 Perl 脚本中的字符串中,我可以 chdir() 到该目录。如果我将此名称插入 PG 表并将其读回(SELECT dirname FROM utfdirs),我无法 chdir 到该目录。但是,屏幕上打印的字符串是相同的,对两个字符串进行 Perl cmp 测试报告它们是相同的,guess_encoding() 报告两者都是 UTF8。

#!/opt/local/bin/perl5.22  
use strict;
use Cwd;
use DBI;
use Encode;
use Encode qw/from_to/;
use Encode::Detect;
use Encode::Guess;
use Encode::UTF8Mac;
#
Encode::Guess->add_suspects(qw/utf-8-mac/);
#
my $dbname = 'test';
my $dbh = DBI->connect("dbi:Pg:dbname=$dbname;host=localhost");
$dbh->do("SET client_min_messages TO WARNING");
#
my $homeDir = '/Users/jldasch';
chdir($homeDir) or die "Cannot cd to [$homeDir]\n";
opendir(D,".");
my @tdlist = sort grep(/(Lambda?)|(Delta?)/,readdir(D));
closedir(D);
$dbh->do("DELETE FROM utfdirs");
my $ins = $dbh->prepare("INSERT INTO utfdirs (dirname) VALUES (?)");
foreach my $d (@tdlist) {
    chdir($homeDir);
    my $ok = chdir($d) ? 1 : 0;
    my $fp = "${homeDir}/${d}";
    printf("%2d %s\n",$ok,$fp);
    $ins->execute($fp);
}
my $rset = $dbh->selectall_arrayref("SELECT dirname FROM utfdirs ORDER BY dirname");
my $i = 0;
foreach my $r (@$rset) {
    my $dbdir = $r->[0];
    my $pdir = ${homeDir} . '/' . $tdlist[$i++];
    print "$r->[0]  $pdir\n";
    my $encPerl = guess_encoding($pdir);
    my $encDb = guess_encoding($dbdir);
    print "Perl Encoding [$encPerl->{Name}]\n";
    print "Db   Encoding [$encDb->{Name}]\n";
    unless ( chdir($dbdir) ) {
    print "Cannot CD to DbDir [$dbdir]\n";
    print "DbDir and PerlDir Match\n" if ($dbdir eq $pdir)
}
exit;

输出:

bash-3.2$ ./utfstuff2.pl 
1 /Users/jldasch/DeltaΔ
1 /Users/jldasch/Lambdaλ
/Users/jldasch/DeltaΔ  /Users/jldasch/DeltaΔ
Perl Encoding [utf8]
Db   Encoding [utf8]
Cannot CD to DbDir [/Users/jldasch/DeltaΔ]
DbDir and PerlDir Match
/Users/jldasch/Lambdaλ  /Users/jldasch/Lambdaλ
Perl Encoding [utf8]
Db   Encoding [utf8]
Cannot CD to DbDir [/Users/jldasch/Lambdaλ]
DbDir and PerlDir Match

所以在我目前检查的级别上,Perl 告诉我字符串是相同的(cmp 和guess_encoding()),它们打印相同,但它们不一样。

如何将 Postgresql 返回的 UTF8 字符串转换为(在 Perl 中)被接受为 chdir() 的有效目录名的字符串?

【问题讨论】:

  • 有一个模块 Encode::UTF8Mac 似乎可以解决这个问题。 my $macOkDir = Encode::decode('utf-8-mac',$dbDir)
  • 使用Devel::Peek 比较有编码问题的字符串。请使用Devel::Peek::Dump 显示$dbdir$pdir 的输出
  • 字符串是完全相同的字节吗?我想知道这里是否存在 precomposed-vs-decomposed-representation 问题。

标签: perl postgresql utf-8


【解决方案1】:

有一个模块 Encode::UTF8Mac 似乎可以解决这个问题。

my $macOkDir = Encode::decode('utf-8-mac',$dbDir)

– 约翰·达施巴赫

【讨论】:

    猜你喜欢
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    相关资源
    最近更新 更多