展开全部
那个数据库并不能自动地处理汉字,相当于它把所有数据当成单字节来处32313133353236313431303231363533e78988e69d8331333335333065理,因此,数据倒底是什么取决于读取它的程序如何理解,数据库本身只负责保存 byte 而不是我们期望的 char。
US7ASCII 是单 byte,而汉字是至少双byte.
所以,如果不做任何转换的话,处理过程中写入和读出都要使用相同的字符集才能理解它,但我们不应该依然数据库服务器和应用服务器或操作系统的字符集是什么,如果不做转换就要求应用服务器,操作系统,数据库的操作系统这些地方都有一致的约定,而实际上这不现实,你不能要求客户的机器按你的要求做,它们现在用 US7ASCII 就表示它们以前有其它系统也用这个数据库,因此你不能再提出任何假设,只能自己用技术方法消化掉。
因此我们要在处理中将汉字保存到数据库之前就事先转换成纯粹的 ASCII 字符串,像 \u0A0c 啥的。String 有一个叫 codePoint 的数字,它是 Unicode Code Point,我们在判断它是非 ASCII 字符时 ( > 256) 时通过翻译把它变成 \u0A0C 再保存,读取时发现了 \u0A0C 再翻译回来。
这本身就是我们在保存 Properties 文件时做的那样,记得 Struts 之类的那个 Properties ResourceBundle 么,我们在 命令行做 native2ascii 时就是这么做的,反编译一下 JDK 的 tools.jar 里面的那个类来看源码,这个转换其实很简单的,我们把 JDK native2ascii 功能嵌入到你的程序中,凡是可能包括汉字的字段(比如,名字,地址,描述)都来一次转换。
下面反编译它,写出(编码过程特简单),读出(解码过程略复杂)需要按长度来试探,并且在未读取完整时把余下的零头先缓存起来,等后面几个字节读取出来之后再拼起来尝试是否是一个\u 开头的符号。当然就算看不明白也没关系,把这段代码的变量改个名字原样贴到你的代码中用就行了,只是我们需要修改那个 Main.class,因为它是命令行程序,有一个 System.exit() 调用需要去掉,另外把收集参数的地方改成我们直接传入参数。