2012-09-26 34 views
2

我的MySQL数据库编码ut8_generic_ci当我使用DBI 并将其存储在$变量并运行此变量的lenght功能我得到一个数字lenght从数据库中读取一些文本字段使用长度和编码用Perl

my $data retrive_text_from_db(); #using dbi 
    print length $data; 

但是当我的$的数据存储在一个文本文件,然后尝试读取它的另一个脚本并运行长度的功能我得到有时不同长度

 open T, '<' ,'file.txt' or die $!; 
    binmode(T, ":utf8"); 
    my $text; 
    {local $/; $text=<T>; } 
    print length $text; 

也有人遇到此问题/有人能告诉什么可能是根o如果问题存在,我该如何解决?

+0

在使用调用'length'之前,你不需要'decode'吗? – Zaid

+0

Mike Whittaker关于Perl和Unicode的演讲中的幻灯片可能会有所帮助 - http://www.slideshare.net/Penfold/perl-and-unicode –

回答

3

Perl字符串既可以是字节型的,也可以是字符型的。我假设你第一个例子报告的长度总是大于或等于第二个例子报告的长度?

当您使用binmode(T, ":utf8")时,您告诉Perl在文件中接收字节流,并使用UTF-8编码自动将它们转换为字符。所以在这个例子中$text应该是一个字符串。

我的猜测是你没有配置DBI来执行这个转换,因此你最终得到一个包含UTF-8编码数据的字节串。这意味着某些字符每个可能需要2-4个字节。一种选择是将DBI配置为正确处理UTF-8。如何做到这一点取决于驱动程序,因为你使用MySQL,应该通过连接这样的工作:

my $dbh = DBI->connect($dsn, $user, $passwrod, { mysql_enable_utf8 => 1 }); 

出于某种原因,此配置变量的缺省值似乎是关闭。

或者你可以自己做转换与编码模块:

use Encode; 
$data = decode_utf8($data); 
+0

没有我的第一个示例报告的长度小于或等于报告的长度第二个例子 – smith

+0

即使我从控制台运行以下mysql查询,它也不管DBI如何,我得到的结果与dbi相同:从info中选择长度(数据)id = 7 – smith

0

试试这里的第一件事就是印双方$data$text屏幕,看看他们是相同的。如果你有字符编码问题,其中一个可能会失败。在这种情况下,请按照pmakholm的建议查看encode模块。

如果测试成功,这是更微妙的东西。

其中一种可能性是换行符在输入数据和文本文件之间存储方式不同。在某些格式中,换行符是一个字符;在另一些情况下,它们是两个字符。即使数据实际上是相同的,这会给你不同的长度。