1. 程式人生 > >java中unicode utf-8以及漢字之間的轉換工具類

java中unicode utf-8以及漢字之間的轉換工具類

1.       漢字字串與unicode之間的轉換

1.1          stringToUnicode

/**
 * 獲取字串的unicode編碼
 * 漢字“木”的Unicode 碼點為Ox6728
 *
 * @param s 木
 * @return \ufeff\u6728  \ufeff控制字元 用來表示「位元組次序標記(Byte Order Mark)」不佔用寬度
 * 在java中一個char是採用unicode儲存的 佔用2個位元組 比如 漢字木 就是 Ox6728 4bit+4bit+4bit+4bit=2位元組
 */
public static String stringToUnicode(String s) {
	try {
		StringBuffer out = new StringBuffer("");
		//直接獲取字串的unicode二進位制
		byte[] bytes = s.getBytes("unicode");
		//然後將其byte轉換成對應的16進製表示即可
		for (int i = 0; i < bytes.length - 1; i += 2) {
			out.append("\\u");
			String str = Integer.toHexString(bytes[i + 1] & 0xff);
			for (int j = str.length(); j < 2; j++) {
				out.append("0");
			}
			String str1 = Integer.toHexString(bytes[i] & 0xff);
			out.append(str1);
			out.append(str);
		}
		return out.toString();
	} catch (UnsupportedEncodingException e) {
		e.printStackTrace();
		return null;
	}
}

測試

    @Test
    public void testGetUnicode() throws Exception {
        String str = "木";
        String s = EncodeUtil.stringToUnicode(str);
        System.out.println(s);  //Ox6728
    }

1.2          unicodeToString

/**
     * Unicode轉 漢字字串
     *
     * @param str \u6728
     * @return '木' 26408
     */
public static String unicodeToString(String str) {

	Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
	Matcher matcher = pattern.matcher(str);
	char ch;
	while (matcher.find()) {
		//group 6728
		String group = matcher.group(2);
		//ch:'木' 26408
		ch = (char) Integer.parseInt(group, 16);
		//group1 \u6728
		String group1 = matcher.group(1);
		str = str.replace(group1, ch + "");
	}
	return str;
}

測試

    @Test
    public void testUnicodeToString() throws Exception {
        String str = "\\u6728";
        String s = EncodeUtil.unicodeToString(str);
        System.out.println(s);  //木
    }

2.       漢字字串與UTF-8之間的轉換

2.1          ConvertStringToUTF8

/**
 * 漢字 轉換為對應的 UTF-8編碼
 * @param s 木
 * @return E69CA8
 */
public static String convertStringToUTF8(String s) {
	if (s == null || s.equals("")) {
		return null;
	}
	StringBuffer sb = new StringBuffer();
	try {
		char c;
		for (int i = 0; i < s.length(); i++) {
			c = s.charAt(i);
			if (c >= 0 && c <= 255) {
				sb.append(c);
			} else {
				byte[] b;
				b = Character.toString(c).getBytes("utf-8");
				for (int j = 0; j < b.length; j++) {
					int k = b[j];
					//轉換為unsigned integer  無符號integer
					/*if (k < 0)
						k += 256;*/
					k = k < 0? k+256:k;
					//返回整數引數的字串表示形式 作為十六進位制(base16)中的無符號整數
					//該值以十六進位制(base16)轉換為ASCII數字的字串
					sb.append(Integer.toHexString(k).toUpperCase());

					// url轉置形式
					// sb.append("%" +Integer.toHexString(k).toUpperCase());
				}
			}
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
	return sb.toString();
}

測試

@Test
public void testConvertStringToUTF8() {
	String str = "木";
	String s = EncodeUtil.convertStringToUTF8(str);
	System.out.println(s);  //E69CA8
}

2.2          ConvertUTF-8ToString

/**
 * UTF-8編碼 轉換為對應的 漢字
 *
 * @param s E69CA8
 * @return 木
 */
public static String convertUTF8ToString(String s) {
	if (s == null || s.equals("")) {
		return null;
	}
	try {
		s = s.toUpperCase();
		int total = s.length() / 2;
		//標識位元組長度
		int pos = 0;
		byte[] buffer = new byte[total];
		for (int i = 0; i < total; i++) {
			int start = i * 2;
			//將字串引數解析為第二個引數指定的基數中的有符號整數。
			buffer[i] = (byte) Integer.parseInt(s.substring(start, start + 2), 16);
			pos++;
		}
		//通過使用指定的字符集解碼指定的位元組子陣列來構造一個新的字串。
		//新字串的長度是字符集的函式,因此可能不等於子陣列的長度。
		return new String(buffer, 0, pos, "UTF-8");
	} catch (UnsupportedEncodingException e) {
		e.printStackTrace();
	}
	return s;
}

測試

@Test
public void testConvertUTF8ToString() {
	String str = "E69CA8";
	String s = EncodeUtil.convertUTF8ToString(str);
	System.out.print(s);  //木
}

3.       unicode與utf-8之間的轉換

3.1          unicode轉為utf8

//將unicode轉換為utf-8
@Test
public void testUnicodeToUtf8() {
	String str = "\\u6728";
	//unicode轉換為String String再轉換為utf-8
	String s = EncodeUtil.convertStringToUTF8(EncodeUtil.unicodeToString(str));
	System.out.println(s);
}

3.2          utf8轉為unicode

//將utf-8轉換為unicode
@Test
public void testUTF8ToUnicode() {
	String str = "E69CA8";
	//utf-8先轉String String再轉unicode
	String s = EncodeUtil.stringToUnicode(EncodeUtil.convertUTF8ToString(str));
	System.out.println(s);
}

總結來說:

1. java中的一個char是兩個位元組,以unicode方式儲存在記憶體中。

2. 一個典型的錯誤是

String s = new String(”木”.getBytes(“utf-8”),”gbk”);

為什麼會報錯呢?原因是 utf-8編碼的位元組陣列怎能使用gbk來解析呢?一個漢字在utf-8下佔用3個位元組,而在gbk下佔用2個位元組,是無法解析的。

3. java中提供了將漢字編碼為utf8的方法 UrlEncoder.encode()以及解碼的方法UrlDecoder.decode()



參考: