基于.NET的轻量级ORM框架及数据库工具集(六)

解决Informix中文乱码问题

一、Informix中文乱码问题

可能很多朋友已经发现,使用Informix CSDK 2.7以上版本连接Informix服务器时,客户端得到的中文字符是乱码。我研究了一些Informix资料,发现这个问题的原因在于这些Informix数据库都没有使用中文LOCALE如GB18030,而使用了Informix默认的en_US.819。

Informix有多语言支持功能The Global Language Support (GLS)。GLS涉及到以下三个概念:

  • LOCALE:即语言、区域、时间、书写方向等的总称,分为服务器端的DBLOCALE和客户端的CLIENTLOCALE;
  • code-set files:字符集文件;
  • code-set conversion files:字符集转换文件。

Informix服务器在创建数据库时应该指定符合所在区域文字习惯的DBLOCALE。如果不指定,则会采用默认的en_US.8859-1,美国英语及ISO 8859-1字符集。

Informix的客户端同样也需要指定合适的CLIENTLOCALE。当DBLOCALE或CLIENTLOCALE与实际存储的文字不符时,就会出现乱码。

有许多从上个世纪就开始使用Informix数据库的国内用户并不清楚GLS的作用,在初建数据库时都采用了默认的LOCALE。然而在早期(Informix CSDK 2.7版以前)Informix支持“GIGO”(垃圾入垃圾出)的策略,默认的LOCALE下仍可以处理中文,所以问题并没有暴露。Informix CSDK2.7以上版本后不再继续支持GIGO,字符串一律按照配置的LOCALE解释,当中文字符使用en_US.8859-1代码集解释时,就出现了乱码。

以下程序演示了一个字符串被GB编码存入数据库,再从数据库中取出后被8859-1解码变成乱码的过程。

        
//解决Informix乱码
private void informixEncoder(string text)
{
    //ISO 8859-1编码器
    Encoding Encoder_ISO8859 = Encoding.GetEncoding("ISO-8859-1");
 
    //GB18030编解码器
    Encoding Encoder_GB18030 = Encoding.GetEncoding("GB18030");
        
    //编码后的字节流缓冲区
    byte[] buffer;
    
        try
            {
                //text是从Informix数据库取出的中文字符串,直接显示为乱码
                //将原始字符按GB编码
                buffer =Encoder_GB18030.GetBytes(text);

                //显示字节流内容
                txtEncoding.Clear();
                foreach(byte item inbuffer)
                {
                   txtEncoding.AppendText(item.ToString("X")+ " ");
                }
 
                //再以ISO 8859-1解码,显示正常
                txtString8859.Text =Encoder_ISO8859.GetString(buffer);
 
                //以GB解码,显示为乱码
                txtStringGB.Text =Encoder_GB18030.GetString(buffer);
 
            }
            catch(Exception ex)
            {
 
            }
   }

以下是程序运行的结果:

原始字符“Informix 中文乱码问题”经过终端软件的GB编码后,变成了“49 6E 66 6F 72 6D 69 78 20 D6 D0 CE C4 C2 D2 C2 EB CE CA CC E2”字节流,被Informix SERVER以8859-1的名义存入了数据库。用户读取数据时,数据库以8859-1进行解码,变成了“Informix ÖÐÎÄÂÒÂëÎÊÌâ”。

进一步测试说明,如果把这些字节流强行按GB解码,则得到了正确的结果。由此可见,从ISO 8859-1到GB的转换具有可行性。

二、DBHelper2的代码转换功能

DBHelper2已内置了以上的代码转换功能,要解决Informix中文乱码问题,仅仅需要在数据库连接串中配置一个选项:

ConvertEncoding=true

使用DBHelper2进行转码只是一个权宜之计,最好的做法当然是合理配置Informix,使用正确的DBLOCALE和CLIENTLOCALE。如果LOCALE与实际语言不匹配,不仅仅只是一个乱码的问题,更会涉及到对字符的排序、检索等字符相关计算的错误。

源代码:https://github.com/alibary/DBHelper2.git 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值