• 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;
                }
            }

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

     七、小结

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

  • 相关阅读:
    ORM之聚合和分组查询
    ORM之ManyToManyField操作
    ORM之ForeignKey操作
    ORM之一般操作
    ORM之元信息
    js浮点数的加减乘除
    如何用js去判断当前是否在微信中打开的链接页面
    Vue应用框架整合与实战--Vue技术生态圈篇
    图片纯前端JS压缩的实现
    js要怎么接收后端传的excel文件流?
  • 原文地址:https://www.cnblogs.com/qiyueliuguang/p/16399563.html
Copyright © 2020-2023  润新知