Java中String字符編碼(CharSet)轉換的相關問題

有用的資料

最近在字符編碼上遇到一些問題,查閱了很多資料,有了一點領悟。以下是幾個比較重要的資料:

《徹底搞懂字符編碼》:http://blog.csdn.net/softman11/article/details/6124345

《深入分析 Java 中的中文編碼問題》:http://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/

看了以上兩篇文章,基本就能搞懂字符編碼問題了。


下面是關於Java的字符編碼問題的一個帖子,解釋了Java的String中的字符存儲問題:

http://stackoverflow.com/questions/12187645/java-utf8-encoding-char-string-types


個人小結:

在任何平臺上,String中的char[]都是UTF-16類型的數組。String的所有操作都是在這個char[]上完成的。

JavaString是一箇中間結果,可以通過getBytes(charset)函數得到指定編碼的byte[]

String.getBytes(charset)實際上是將UTF-16數組按照對應的charset編碼爲byte[]。網絡程序中,將byte[]傳輸到其他平臺,其他平臺再用new String(byte[], charset)byte[]轉化爲該平臺本地的UTF-16字符串。

網上有一種轉化字符串編碼的方法:

String newString=new String(oldString.getBytes(oldCharSet),newCharSet),這種方式實際上沒有任何意義,純屬誤導下面簡單解釋一下。

以上轉換的初衷通常是想在控制檯(或文件)輸出字符串。亂碼是由於控制檯(或文件)通常是GBKUTF-8的,而Stringchar[]UTF-16類型的。這時就需要使用 String.getBytes("GBK") 或者 String.getBytes("UTF-8") 得到byte[],然後使用 OutputStream.write(byte[]) 即可得到正確的輸出。

另外,UTF-8通常比較省空間,一般通過String.getBytes("UTF-8")得到byte[],再進行網絡傳輸。


示例程序

下面的程序簡單的展示了這個過程:

import java.io.*;
public class TestCharSetConvert {	
	/*程序功能:
	 * 從文件中讀入數據,以其他編碼輸出到其他文件中
	 */
	public static void main(String[] args){		
		//首先在程序目錄下創建一個GBK編碼的名爲GBK.txt,裏面可以包含任何漢字和英文等
		String inCharsetName="GBK";
		String[] outCharsetNames=new String[]{"GBK","GB2312","Unicode","UTF-8","UTF-16"};
		
		String content=readStringByStream(inCharsetName+".txt",inCharsetName);
		for(String outCharsetName: outCharsetNames){
			writeStringByStream(content,outCharsetName+".txt",outCharsetName);
		}
	}
	
	public static String readStringByStream(String inFilePath, String inCharsetName){
		try {
			FileInputStream fin=new FileInputStream(inFilePath);
			byte[] bytes=new byte[1024];
			int count=fin.read(bytes);
			String content=new String(bytes,0,count,inCharsetName);//解碼爲UTF-16字符串,inCharsetName必須與文件的字符編碼一致,否則會失敗或產生亂碼
			System.out.format("read %s from %s with charset %s\n\n",content,inFilePath,inCharsetName);
			fin.close();
			return content;
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
	
	public static void writeStringByStream(String content, String outFilePath, String outCharsetName){
		try {
			FileOutputStream fout=new FileOutputStream(outFilePath);
			byte[] bytes=content.getBytes(outCharsetName);//將UTF-16字符串編碼爲指定字符集的字節流
			fout.write(bytes);			
			fout.close();			
			System.out.format("wrote %s to %s with charset %s\n",content,outFilePath,outCharsetName);
		}
		catch (Exception e) {			
			e.printStackTrace();
		}
	}
}

以上程序使用了InputStream和OutputStream以字節流的方式輸入輸出。實際上Java的Reader和Writer已經封裝了這個過程,可以使用它們進行面向字符和字符串的操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章