?? java 編程技術中漢字問題的分析及解決(轉).txt
字號:
static int iCharNum=0;
public static void main(String[] args) {
System.out.println("Input GB2312 file, output Big5 file.");
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;
}
}
}
編碼轉化的過程如下:
ByteToCharGB2312 CharToByteBig5
GB2312------------------>Unicode------------->Big5
執(zhí)行 java gb2big5 gb.txt big5.txt ,如果 gb.txt 的內容是“今天星期三”,則得到的文件 big5.txt 中的字符能夠正確顯示;而如果 gb.txt 的內容是“情人節(jié)快樂”,則得到的文件 big5.txt 中對應于“節(jié)”和“樂”的字符都是符號“?”(0x3F),可見 sun.io.ByteToCharGB2312 和 sun.io.CharToByteBig5 這兩個基本類并沒有編好。
正如上例一樣, Java 的基本類也可能存在問題。由于國際化的工作并不是在國內完成的,所以在這些基本類發(fā)布之前,沒有經(jīng)過嚴格的測試,所以對中文字符的支持并不像 Java Soft 所聲稱的那樣完美。前不久,我的一位技術上的朋友發(fā)信給我說,他終于找到了[B] Java Servlet 中文問題的根源[/B]。兩周以來,他一直為 Java Servlet 的中文問題所困擾,因為每面對一個含有中文字符的字符串都必須進行強制轉換才能夠得到正確的結果(這好象是大家公認的唯一的解決辦法)。后來,他確實不想如此繼續(xù)安分下去了,因為這樣的事情確實不應該是高級程序員所要做的工作,他就找出 Servlet 解碼的源代碼進行分析,因為他懷疑問題就出在解碼這部分。經(jīng)過四個小時的奮斗,他終于找到了問題的根源所在。原來他的懷疑是正確的, Servlet 的解碼部分完全沒有考慮雙字節(jié),直接把 %XX 當作一個字符。(原來 Java Soft 也會犯這幺低級的錯誤!)
如果你對這個問題有興趣或者遇到了同樣的煩惱的話,你可以按照他的步驟[B]對[/B][B] Servlet.jar 進行修改[/B]:
找到源代碼 HttpUtils 中的 static private String parseName ,在返回前將 sb(StringBuffer) 復制成 byte bs[] ,然后 return new String(bs,”GB2312”)。作上述修改后就需要自己解碼了:
HashTable form=HttpUtils .parseQueryString(request.getQueryString())或者
form=HttpUtils.parsePostData(……)
千萬別忘了編譯后放到 Servlet.jar 里面。
五、 關于 Java 中文問題的總結
Java 編程語言成長于網(wǎng)絡世界,這就要求 Java 對多國字符有很好的支持。 Java 編程語言適應了計算的網(wǎng)絡化的需求,為它能夠在網(wǎng)絡世界迅速成長奠定了堅實的基礎。 Java 的締造者 (Java Soft) 已經(jīng)考慮到 Java 編程語言對多國字符的支持,只是現(xiàn)在的解決方案有很多缺陷在里面,需要我們付諸一些補償性的措施。而世界標準化組織也在努力把人類所有的文字統(tǒng)一在一種編碼之中,其中一種方案是 ISO10646 ,它用四個字節(jié)來表示一個字符。當然,在這種方案未被采用之前,還是希望 Java Soft 能夠嚴格地測試它的產(chǎn)品,為用戶帶來更多的方便。
[B]附[/B]一個用于從數(shù)據(jù)庫和網(wǎng)絡中取出[B]中文亂碼的處理函數(shù)[/B],入?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;
}
[b]參考資料[/b][UL][LI][url href=http://smth.org/SMTH2000/bbsdoc?NJava]BBS 水木清華站的 Java 討論區(qū)[/url]
[UL][LI]中國最大的電子公告板的 Java 討論區(qū),有眾多高校的 Java 愛好者在此進行關于 Java 技術的討論 [/LI][/UL][/LI][/UL]
[b]作者簡介[/b] [UL][LI]段明輝([email]duanmh@dns.ime.tsinghua.edu.cn[/email]),清華大學電子工程系學生 [UL][LI]現(xiàn)在正在清華大學微電子學研究所從事 Java 智能卡微處理器的研究和開發(fā) [LI]領導 BBS 水木清華站的 Java 討論組,為眾多 Java 技術應用者提供解決方案 [/LI][/UL][/LI][/UL]
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -