`
linkyou66
  • 浏览: 227902 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

测试过程中遇到字符集问题小结

 
阅读更多
<p>作者:赵璨</p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small;"><span style=""><span style=""></span></span><span style="">这两天我们在用</span><span style="" lang="EN-US">dbunit</span><span style="">插</span><span style="" lang="EN-US">IM</span><span style="">数据库时碰到了乱码问题,初步做了研究,分享一下,可能对其他测试同学也会有点帮助。有错误的地方大家尽管指出。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="" lang="EN-US"><span style="font-size: small;"></span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><strong><span style="">一:理论</span></strong><strong></strong></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small;"><span style="" lang="EN-US"> </span><span style="">编程过程中涉及到的字符集编码问题通常涉及到这样几个因素:</span></span></p>
<p class="MsoNormal" style=""><span style="" lang="EN-US"><span style=""><span style="font-size: small;">1.</span><span style='font: 7pt "Times New Roman";'> </span></span></span><span style="font-size: small;"><span style="">文件编码格式</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt;"><span style="font-size: small;"><span style="">例如</span><span style="" lang="EN-US">XML</span><span style="">文件通过第一行的声明指定了文件的编码格式。</span><span style="" lang="EN-US">Java</span><span style="">中可以通过</span><span style="" lang="EN-US">InputStream</span><span style="">读取文件,用</span><span style="" lang="EN-US">InputStreamReader</span><span style="">来对读取后的字节解码。这些在陈教兽的</span><span style="" lang="EN-US">blog</span><span style="">中也有(</span><span style="color: #9d9d9d;" lang="EN-US"><a title="阿里旺旺无法确定该链接的安全性" href="http://blog.csdn.net/linkyou/archive/2009/03/14/3990547.aspx" target="_blank"><span style="color: gray;"><span style="font-family: Times New Roman;">http://blog.csdn.net/linkyou/archive/2009/03/14/3990547.aspx</span></span></a></span><span style="">),例如:</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt;"><span style="color: black;" lang="EN-US"><span style="font-size: small;"><span style="font-family: Times New Roman;">InputStream is = new FileInputStream("z.xml");  <br>InputStreamReader streamReader = new InputStreamReader(is, "GBK");</span></span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt;"><span style="font-size: small;"><span style="">当然也有用其他方式解码的,例如</span><span style="color: black;" lang="EN-US"><span style="font-family: Times New Roman;">Dom4j</span></span><span style="">等等。</span></span></p>
<p class="MsoNormal" style=""><span style="" lang="EN-US"><span style=""><span style="font-size: small;">2.</span><span style='font: 7pt "Times New Roman";'> </span></span></span><span style="font-size: small;"><span style="" lang="EN-US">JVM</span><span style="">编码格式</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt;"><span style="font-size: small;"><span style="">默认的</span><span style="" lang="EN-US">Java</span><span style="">都是使用</span><span style="" lang="EN-US">Unicode</span><span style="">字符集已做到更好的国际化。因此当需要解析其他字符集的时候,我们需要进行相应的解码。例如:</span></span></p>
<p>
</p>
<table class="MsoNormalTable" style="border-collapse: collapse;" border="0" cellspacing="0" cellpadding="0"><tbody><tr style="">
<td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 426.1pt; padding-top: 0cm; background-color: transparent;" width="568" valign="top">
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> String <span style="background: silver;">s</span> = </span><span style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";' lang="EN-US">"abc"</span><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">;</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> </span><strong><span style='font-size: 10pt; color: #7f0055; font-family: "Courier New";' lang="EN-US">byte</span></strong><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">[] b = <span style="background: silver;">s</span>.getBytes(</span><span style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";' lang="EN-US">"UTF-8"</span><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">);</span></p>
</td>
</tr></tbody></table>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt;"><span style="" lang="EN-US"><span style="font-size: small;"></span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt;"><span style="font-size: small;"><span style="">又或者有另一种方式:</span></span></p>
<p>
</p>
<table class="MsoNormalTable" style="border-collapse: collapse;" border="0" cellspacing="0" cellpadding="0"><tbody><tr style="">
<td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 426.1pt; padding-top: 0cm; background-color: transparent;" width="568" valign="top">
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">String sql = </span><span style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";' lang="EN-US">"abc";</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">String s2 = </span><strong><span style='font-size: 10pt; color: #7f0055; font-family: "Courier New";' lang="EN-US">new</span></strong><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> String(sql.getBytes(</span><span style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";' lang="EN-US">"GBK"</span><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">), </span><span style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";' lang="EN-US">"ISO8859-1"</span><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">);</span></p>
</td>
</tr></tbody></table>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt;"><span style="font-size: small;"><span style="">这个如何解释?不能直接理解为将</span><span style="" lang="EN-US">GBK</span><span style="">转为</span><span style="" lang="EN-US">ISO8859-1</span><span style="">。而是应该理解为字符串</span><span style="" lang="EN-US">sql</span><span style="">用</span><span style="" lang="EN-US">GBK</span><span style="">解码还原为原始字节数组,再用</span><span style="" lang="EN-US">ISO8859-1</span><span style="">解码成正确的字符串。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt;"><span style="" lang="EN-US"><span style="font-size: small;"></span></span></p>
<p class="MsoNormal" style=""><span style="" lang="EN-US"><span style=""><span style="font-size: small;">3.</span><span style='font: 7pt "Times New Roman";'> </span></span></span><span style="font-size: small;"><span style="">数据库编码格式</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt;"><span style="font-size: small;"><span style="">这个又复杂了一点,就谈</span><span style="" lang="EN-US">Oracle</span><span style="">的字符集,分成服务端和客户端。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt;"><span style="font-size: small;"><span style="">服务端上,</span><span style="" lang="EN-US">us7ascii</span><span style="">是</span><span style="" lang="EN-US">Oracle</span><span style="">最早支持的编码方案,是单字节编码的。现在为了支持国际化,一般都采用</span><span style="" lang="EN-US">unicode</span><span style="">编码了。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 42pt;"><span style="font-size: small;"><span style="">客户端上,是通过</span><span style="" lang="EN-US">NLS_LANG</span><span style="">指定编码方式的,任何发自或发往客户端的数据都是用客户端定义的字符集编码。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="" lang="EN-US"><span style="font-size: small;"></span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><strong><span style="">二:实战</span></strong><strong></strong></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small;"><span style="" lang="EN-US"> </span><span style="">好,现在回到我们的问题:</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small;"><span style="" lang="EN-US">1. </span><span style="">为什么数据库编码为</span><span style="" lang="EN-US">us7ascii</span><span style="">时,我们用</span><span style="" lang="EN-US">dbunit</span><span style="">插数据会出现乱码?</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small;"><span style="">因为:</span><span style="" lang="EN-US">1. </span><span style="">我们的</span><span style="" lang="EN-US">xml</span><span style="">数据文件编码是</span><span style="" lang="EN-US">UTF-8</span><span style="">:</span><span style="" lang="EN-US"> &lt;?xml version="1.0" encoding="UTF-8"?&gt;</span></span></p>
<p class="MsoNormal" style=""><span style="" lang="EN-US"><span style=""><span style="font-size: small;">2.</span><span style='font: 7pt "Times New Roman";'> </span></span></span><span style="font-size: small;"><span style="" lang="EN-US">JVM</span><span style="">编码默认是</span><span style="" lang="EN-US">GBK</span><span style="">,可能大家不同的系统会略有区别,不过应该都是</span><span style="" lang="EN-US">Unicode</span><span style="">双字节编码:可以通过</span><span style="" lang="EN-US">Charset.defaultCharset()</span><span style="">查看默认编码</span></span></p>
<p class="MsoNormal" style=""><span style="" lang="EN-US"><span style=""><span style="font-size: small;">3.</span><span style='font: 7pt "Times New Roman";'> </span></span></span><span style="font-size: small;"><span style="" lang="EN-US">IM</span><span style="">数据库服务端编码是</span><span style="" lang="EN-US">us7ascii</span><span style="">,客户端也要用</span><span style="" lang="EN-US">us7ascii</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 25.5pt;"><span style="font-size: small;"><span style="">首先</span><span style="" lang="EN-US">dbunit</span><span style="">读取</span><span style="" lang="EN-US">utf-8</span><span style="">的文件,默认情况下却用双字节的</span><span style="" lang="EN-US">gbk</span><span style="">解码,然后插入到单字节编码规范的数据库中,肯定出现乱码。</span></span></p>
<p class="MsoNormal" style=""><span style="" lang="EN-US"><span style=""><span style="font-size: small;">2.</span><span style='font: 7pt "Times New Roman";'> </span></span></span><span style="font-size: small;"><span style="">如何解决?</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 21pt;"><span style="font-size: small;"><span style="">最好是编码格式统一,当然数据库的编码格式我们不能改。我们能够改的是</span><span style="" lang="EN-US">xml</span><span style="">文件:</span><span style="" lang="EN-US"> &lt;?xml version="1.0" encoding="GBK"?&gt;</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 21pt;"><span style="font-size: small;"><span style="" lang="EN-US">Ok</span><span style="">,现在前两步统一编码了,现在要做的是在插入数据库之前在</span><span style="" lang="EN-US">java</span><span style="">代码中用对应</span><span style="" lang="EN-US">us7ascii</span><span style="">的编码格式做一次解码,对应的编码规范是“</span><span style="" lang="EN-US">ISO8859-1<span style="" lang="EN-US"><span lang="EN-US">”</span></span></span><span style="">。这里我们</span><span style="" lang="EN-US">Dbunit</span><span style="">的代码要做一下改进,陈洪看看,更新一下代码。</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt 21pt;"><span style="font-size: small;"><span style="">具体代码如下:</span></span></p>
<p>
</p>
<table class="MsoNormalTable" style="border-collapse: collapse;" border="0" cellspacing="0" cellpadding="0"><tbody><tr style="">
<td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 426.1pt; padding-top: 0cm; background-color: transparent;" width="568" valign="top">
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> DbUnit db = </span><strong><span style='font-size: 10pt; color: #7f0055; font-family: "Courier New";' lang="EN-US">new</span></strong><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> DbUnit(</span><span style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";' lang="EN-US">"oracle.jdbc.driver.OracleDriver"</span><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">,</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> </span><span style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";' lang="EN-US">"jdbc:oracle:thin:@10.2.225.81:1521:asoft"</span><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">, </span><span style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";' lang="EN-US">"aliim"</span><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">,</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> </span><span style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";' lang="EN-US">"aliim"</span><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">);</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> db.setSchema(</span><span style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";' lang="EN-US">"ALIIM"</span><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">);</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> String path = </span><span style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";' lang="EN-US">"util//z.xml"</span><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">;</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> FileInputStream stream = </span><strong><span style='font-size: 10pt; color: #7f0055; font-family: "Courier New";' lang="EN-US">new</span></strong><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> FileInputStream(path);</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><strong><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> //</span></strong><strong><span style="">用</span></strong><strong><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">InputStreamReader</span></strong><strong><span style="">的构造函数对读取的字节流做</span></strong><strong><span style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";' lang="EN-US">ISO8859-1</span></strong><strong><span style="">的解码</span></strong><strong></strong></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><strong><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> InputStreamReader reader = </span></strong><strong><span style='font-size: 10pt; color: #7f0055; font-family: "Courier New";' lang="EN-US">new</span></strong><strong><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> InputStreamReader(stream, </span></strong><strong><span style='font-size: 10pt; color: #2a00ff; font-family: "Courier New";' lang="EN-US">"ISO8859-1"</span></strong><strong><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">);</span></strong></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style='font-size: 10pt; font-family: "Courier New";' lang="EN-US"></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> FlatXmlDataSet dataSet = </span><strong><span style='font-size: 10pt; color: #7f0055; font-family: "Courier New";' lang="EN-US">new</span></strong><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> FlatXmlDataSet(reader);</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US"> DatabaseOperation.</span><em><span style='font-size: 10pt; color: #0000c0; font-family: "Courier New";' lang="EN-US">INSERT</span></em><span style='font-size: 10pt; color: black; font-family: "Courier New";' lang="EN-US">.execute(db.getConnection(), dataSet);</span></p>
</td>
</tr></tbody></table>
分享到:
评论

相关推荐

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    3.4 小结:基本数据类型—— Java中一切数据和运算的基础 63 3.5 习题 65 第4章 Java中的程序执行流程 67 教学视频:1小时57分钟 4.1 顺序执行 67 4.2 使用if-else让程序懂得判断 68 4.2.1 if语句 68 4.2.2 ...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    3.4 小结:基本数据类型—— Java中一切数据和运算的基础 63 3.5 习题 65 第4章 Java中的程序执行流程 67 教学视频:1小时57分钟 4.1 顺序执行 67 4.2 使用if-else让程序懂得判断 68 4.2.1 if语句 68 4.2.2 ...

    C语言入门经典(第4版)--源代码及课后练习答案

    1.10 小结 18 1.11 习题 18 第2章 编程初步 19 2.1 计算机的内存 19 2.2 什么是变量 21 2.3 存储数值的变量 21 2.3.1 整数变量 21 2.3.2 变量的命名 25 2.3.3 变量的使用 26 2.3.4 变量的初始化 28 2.3.5 ...

    3.ASP.NET 2.0 入门经典(第4版) [压缩包1/10]

    1.8 本章小结 24 1.9 练习 25 第2章 站点设计 27 2.1 总体设计目标 27 2.2 Master和Content页面 28 2.2.1 创建Master页面 29 2.2.2 创建Content页面 31 2.2.3 Master和Content页面的示例 32 2.2.4 在Master...

    亮剑.NET深入体验与实战精要2

    本书既考虑到实际开发中经常遇到的困惑和难题,也分析了解决问题的思路和方法,更总结出项目开发中不可或缺的技术点及思想。读者可以在欣赏一个个有趣例子的过程中,不知不觉具备开发真正商业项目的能力。 本书集...

    亮剑.NET深入体验与实战精要3

    本书既考虑到实际开发中经常遇到的困惑和难题,也分析了解决问题的思路和方法,更总结出项目开发中不可或缺的技术点及思想。读者可以在欣赏一个个有趣例子的过程中,不知不觉具备开发真正商业项目的能力。 本书集...

    C#微软培训资料

    14.4 继承中关于属性的一些问题.169 14.5 小 结 .172 第四部分 深入了解 C#.174 第十五章 接 口 .174 15.1 组件编程技术 .174 15.2 接 口 定 义 .177 15.3 接口的成员 .178 15.4 接口的实现 .182 ...

    rar压缩软件.rar

    但是可以使用 -sc&lt;字符集&gt;l 开关重定义。 你可以在同一命令行指定普通文件名和列表文件。如果文件和列表 文件都未被指定,那么 RAR 将默认是 *.*,来处理所有文件。 许多 RAR 命令,例如解压、测试和列表,都...

    asp.net知识库

    C#静态成员和方法的学习小结 C#中结构与类的区别 C#中 const 和 readonly 的区别 利用自定义属性,定义枚举值的详细文本 Web标准和ASP.NET - 第一部分 XHTML介绍 在ASP.NET页面中推荐使用覆写(Override)而不是事件...

    WinRAR_4.0.exe

    如果在命令行或配置文件中指定开关 -ilog ,RAR 将会把处理压缩文件中遇到的错误 等写到日志文件中。读取开关 -ilog 描述获得更多信息。 固实压缩的文件列表 - rarfiles.lst rarfiles.lst 包含一个用户定义...

    c++ 面试题 总结

    ==strcpy拷贝的结束标志是查找字符串中的\0 因此如果字符串中没有遇到\0的话 会一直复制,直到遇到\0,上面的123都因此产生越界的情况 建议使用 strncpy 和 memcpy ---------------------------------------------...

Global site tag (gtag.js) - Google Analytics