一、背景
公司需要把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; } }
下面是经过处理前后的数据对比图,看到熟悉的中文,说明解决方案没有问题。
七、小结
可以看到这个处理很耗时,路过的各路大神,如果有更好的处理方法,请给我留言。谢谢!