?? java 編程技術(shù)中漢字問題的分析及解決(轉(zhuǎn)自ibm).txt
字號:
if (args.length!=2) {
System.err.println("Usage: jview gb2big5 gbfile big5file");
System.exit(1);
}
String inputString = readInput(args[0]);
writeOutput(inputString,args[1]);
System.out.println("Number of Characters in file: "+iCharNum+".");
}
static void writeOutput(String str, String strOutFile) {
try {
FileOutputStream fos = new FileOutputStream(strOutFile);
Writer out = new OutputStreamWriter(fos, "Big5");
out.write(str);
out.close();
}
catch (IOException e) {
e.printStackTrace();
e.printStackTrace();
}
}
static String readInput(String strInFile) {
StringBuffer buffer = new StringBuffer();
try {
FileInputStream fis = new FileInputStream(strInFile);
InputStreamReader isr = new InputStreamReader(fis, "GB2312");
Reader in = new BufferedReader(isr);
int ch;
while ((ch = in.read()) > -1) {
iCharNum += 1;
buffer.append((char)ch);
}
in.close();
return buffer.toString();
}
catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
編碼轉(zhuǎn)化的過程如下:
ByteToCharGB2312 CharToByteBig5
GB2312------------------>Unicode------------->Big5
執(zhí)行 java gb2big5 gb.txt big5.txt ,如果 gb.txt 的內(nèi)容是“今天星期三”,則得到的文件 big5.txt 中的字符能夠正確顯示;而如果 gb.txt 的內(nèi)容是“情人節(jié)快樂”,則得到的文件 big5.txt 中對應(yīng)于“節(jié)”和“樂”的字符都是符號“?”(0x3F),可見 sun.io.ByteToCharGB2312 和 sun.io.CharToByteBig5 這兩個(gè)基本類并沒有編好。
正如上例一樣, Java 的基本類也可能存在問題。由于國際化的工作并不是在國內(nèi)完成的,所以在這些基本類發(fā)布之前,沒有經(jīng)過嚴(yán)格的測試,所以對中文字符的支持并不像 Java Soft 所聲稱的那樣完美。前不久,我的一位技術(shù)上的朋友發(fā)信給我說,他終于找到了 Java Servlet 中文問題的根源。兩周以來,他一直為 Java Servlet 的中文問題所困擾,因?yàn)槊棵鎸σ粋€(gè)含有中文字符的字符串都必須進(jìn)行強(qiáng)制轉(zhuǎn)換才能夠得到正確的結(jié)果(這好象是大家公認(rèn)的唯一的解決辦法)。后來,他確實(shí)不想如此繼續(xù)安分下去了,因?yàn)檫@樣的事情確實(shí)不應(yīng)該是高級程序員所要做的工作,他就找出 Servlet 解碼的源代碼進(jìn)行分析,因?yàn)樗麘岩蓡栴}就出在解碼這部分。經(jīng)過四個(gè)小時(shí)的奮斗,他終于找到了問題的根源所在。原來他的懷疑是正確的, Servlet 的解碼部分完全沒有考慮雙字節(jié),直接把 %XX 當(dāng)作一個(gè)字符。(原來 Java Soft 也會(huì)犯這幺低級的錯(cuò)誤!)
如果你對這個(gè)問題有興趣或者遇到了同樣的煩惱的話,你可以按照他的步驟對 Servlet.jar 進(jìn)行修改:
找到源代碼 HttpUtils 中的 static private String parseName ,在返回前將 sb(StringBuffer) 復(fù)制成 byte bs[] ,然后 return new String(bs,”GB2312”)。作上述修改后就需要自己解碼了:
HashTable form=HttpUtils .parseQueryString(request.getQueryString())或者
form=HttpUtils.parsePostData(……)
千萬別忘了編譯后放到 Servlet.jar 里面。
[b]五、 關(guān)于 Java 中文問題的總結(jié) [/b]
Java 編程語言成長于網(wǎng)絡(luò)世界,這就要求 Java 對多國字符有很好的支持。 Java 編程語言適應(yīng)了計(jì)算的網(wǎng)絡(luò)化的需求,為它能夠在網(wǎng)絡(luò)世界迅速成長奠定了堅(jiān)實(shí)的基礎(chǔ)。 Java 的締造者 (Java Soft) 已經(jīng)考慮到 Java 編程語言對多國字符的支持,只是現(xiàn)在的解決方案有很多缺陷在里面,需要我們付諸一些補(bǔ)償性的措施。而世界標(biāo)準(zhǔn)化組織也在努力把人類所有的文字統(tǒng)一在一種編碼之中,其中一種方案是 ISO10646 ,它用四個(gè)字節(jié)來表示一個(gè)字符。當(dāng)然,在這種方案未被采用之前,還是希望 Java Soft 能夠嚴(yán)格地測試它的產(chǎn)品,為用戶帶來更多的方便。
附一個(gè)用于從數(shù)據(jù)庫和網(wǎng)絡(luò)中取出中文亂碼的處理函數(shù),入?yún)⑹怯袉栴}的字符串,出參是問題已經(jīng)解決了的字符串。
String parseChinese(String in)
{
String s = null;
byte temp [];
if (in == null)
{
System.out.println("Warn:Chinese null founded!");
return new String("");
}
try
{
temp=in.getBytes("iso-8859-1");
temp=in.getBytes("iso-8859-1");
s = new String(temp);
}
{
System.out.println("Warn:Chinese null founded!");
return new String("");
}
try
{
temp=in.getBytes("iso-8859-1");
s = new String(temp);
}
catch(UnsupportedEncodingException e)
{
System.out.println (e.toString());
}
return s;
}
[hr]
[b]作者簡介[/b]
段明輝,清華大學(xué)電子工程系學(xué)生
現(xiàn)在正在清華大學(xué)微電子學(xué)研究所從事 Java 智能卡微處理器的研究和開發(fā)
領(lǐng)導(dǎo) BBS 水木清華站的 Java 討論組,為眾多 Java 技術(shù)應(yīng)用者提供解決方案
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -