Paradox中文乱码

一、背景

  公司需要把Paradox库中的数据读出来,经过一番操作,最后写入mssql数据库中。

二、环境

  • Windows Server 2003
  • Visual Studio 2008
  • .Net Framework 3.5
  • C#控制台

三、问题

  写入到mssql数据库中的表中存在乱码,且网上搜遍了解决办法绝大部分都不能解决问题(有一个delphi的转码帖子可行,但我不会delphi)。最后发现这是一个微软系列库的bug导致的问题(VB和C#的都不行)。

四、思路

  乱码可能是由于编码问题导致一些中文字符无法正常显示。解决它要么读取Paradox库中的数据时用正确的编码,要么把mssql表中的编码改成和Paradox库的编码一样的。由于mssql库中的数据可能用于其他地方,所以我决定从源头上修正问题。

五、剖析

  既然要从源头上修正问题,那么就要知道Paradox使用的是什么编码,然后找一个乱码数据,它正常的中文显示是什么,他在Paradox中的编码是什么,转换成能放入mssql表中的格式后编码会变成什么样的?

  由于我是第一次接触Paradox,我以为它和mysql等类似,表有指定的编码格式,但我不知道如何获取到Paradox的编码。经过网上查找,我只找到了Paradox和Delphi相关,并且发现Delphi中的Database Desktop能查看Paradox的内容,但网上说Paradox有ascii,Paradox China 936等各种编码,为了搞清楚到底是什么编码,我安装了delphi 7,用Database Desktop查看了Paradox中的中文内容,但Paradox的db文件到底是什么编码格式,我还是不清楚。于是我用010editor打开了Paradox的db库文件,并定位到了某一中文的编码,于是我确定了我这个Paradox库文件采用的是ascii(ansi)编码。

  剩下的就是在vs中查看内存中对应中文的编码,发现它采用的是unicode,但从ascii转成unicode是错的,我发现用odbc从paradox中取得数据后编码就是错的。而取数据这个操作我用的是微软的库,它居然出错了。

  在本次测试中,我查看的是“黑色-”这个中文的原始和最后编码,“黑色-”在Paradox中采用ascii编码,具体编码是:BA DA C9 AB A3 AD,而微软自带的api取出数据后编码变成了:BA 00 DA 00 C9 00 AB 00 A3 00 AD 00,这个看起来好像是unicode,但“黑色-”正确的unicode编码应该是:D1 9E 72 82 0D FF(小端)。于是我就自己写了一个程序处理了这个问题。

六、解决方案

  取出数据后用下面代码处理一下格式即可。

        static string ConvertEncoding(string strSource)
        {
            byte[] arrSource = Encoding.Unicode.GetBytes(strSource);
            byte[] arrDest = new byte[arrSource.Length / 2];
            for (int i = 0; i < arrSource.Length; i = i + 2)
            {
                arrDest[i / 2] = arrSource[i];
            }
            return Encoding.Default.GetString(arrDest);
        }

        static bool ConvertEncoding(DataTable dtInfo)
        {
            try
            {
                foreach (DataRow itemRow in dtInfo.Rows)
                {
                    foreach (DataColumn itemColumn in dtInfo.Columns)
                    {
                        itemRow[itemColumn.ColumnName] = ConvertEncoding(itemRow[itemColumn.ColumnName].ToString());
                    }
                }

                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return false;
            }
        }

  下面是经过处理前后的数据对比图,看到熟悉的中文,说明解决方案没有问题。

 七、小结

  可以看到这个处理很耗时,路过的各路大神,如果有更好的处理方法,请给我留言。谢谢!

posted @ 2022-06-22 10:25  七月流光  阅读(225)  评论(0编辑  收藏  举报