新聞中心
誰能給一個java編碼轉(zhuǎn)換的例子?謝謝
給你些詳細(xì)資料解釋
成都創(chuàng)新互聯(lián)是一家專業(yè)提供冠縣企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、H5高端網(wǎng)站建設(shè)、小程序制作等業(yè)務(wù)。10年已為冠縣眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計公司優(yōu)惠進(jìn)行中。
1、JVM中單個字符占用的字節(jié)長度跟編碼方式有關(guān),而默認(rèn)編碼方式又跟平臺是一一對應(yīng)的或說平臺決定了默認(rèn)字符編碼方式;2、對于單個字符:ISO-8859-1單字節(jié)編碼,GBK雙字節(jié)編碼,UTF-8三字節(jié)編碼;因此中文平臺(中文平臺默認(rèn)字符集編碼GBK)下一個中文字符占2個字節(jié),而英文平臺(英文平臺默認(rèn)字符集編碼Cp1252(類似于ISO-8859-1))。
3、getBytes()、getBytes(encoding)函數(shù)的作用是使用系統(tǒng)默認(rèn)或者指定的字符集編碼方式,將字符串編碼成字節(jié)數(shù)組。
Me結(jié)論:編碼方式?jīng)Q定字節(jié)長度;
在中文平臺下,默認(rèn)的字符集編碼是GBK,此時如果使用getBytes()或者getBytes("GBK"),則按照GBK的編碼規(guī)則將每個中文字符用2個byte表示。所以我們看到"中文"最終GBK編碼結(jié)果就是: -42 -48 -50 -60 。-42和-48代表了"中"字,而"-50"和"-60"則代表了"文"字。
在中文平臺下,如果指定的字符集編碼是UTF-8,那么按照UTF-8對中文的編碼規(guī)則:每個中文用3個字節(jié)表示,那么"中文"這兩個字符最終被編碼成:-28 -72 -83、-26 -106 -121兩組。每3個字節(jié)代表一個中文字符。
在中文平臺下,如果指定的字符集編碼是ISO-8859-1,由于此字符集是單字節(jié)編碼,所以使用getBytes("ISO-8859-1")時,每個字符只取一個字節(jié),每個漢字只取到了一半的字符。另外一半的字節(jié)丟失了。由于這一半的字符在字符集中找不到對應(yīng)的字符,所以默認(rèn)使用編碼63代替,也就是?。
在英文平臺下,默認(rèn)的字符集編碼是Cp1252(類似于ISO-8859-1),如果使用GBK、UTF-8進(jìn)行編碼,得到的字節(jié)數(shù)組依然是正確的(GBK4個字節(jié),UTF-8是6個字節(jié))。因?yàn)樵贘VM內(nèi)部是以Unicode存儲字符串的,使用getBytes(encoding)會讓JVM進(jìn)行一次Unicode到指定編碼之間的轉(zhuǎn)換。對于GBK,JVM依然會轉(zhuǎn)換成4個字節(jié),對于UTF-8,JVM依然會轉(zhuǎn)換成6個字節(jié)。但是對于ISO-8859-1,則由于無法轉(zhuǎn)換(2個字節(jié)---1個字節(jié),截取了一半的字節(jié)),所以轉(zhuǎn)換后的結(jié)果是錯誤的。
相同的平臺下,同一個中文字符,在不同的編碼方式下,得到的是完全不同的字節(jié)數(shù)組。這些字節(jié)數(shù)組有可能是正確的(只要該字符集支持中文),也可能是完全錯誤的(該字符集不支持中文)。
記住:
不要輕易地使用或?yàn)E用String類的getBytes(encoding)方法,更要盡量避免使用getBytes()方法。因?yàn)檫@個方法是平臺依賴的,在平臺不可預(yù)知的情況下完全可能得到不同的結(jié)果。如果一定要進(jìn)行字節(jié)編碼,則用戶要確保encoding的方法就是當(dāng)初字符串輸入時的encoding。
【結(jié)論】字節(jié)數(shù)組轉(zhuǎn)換成字符串,然后轉(zhuǎn)換成字符數(shù)組問題:
________________________________________
和getBytes(encoding)不同,toCharArray()返回的是"自然字符"。但是這個"自然字符"的數(shù)目和內(nèi)容卻是由原始的編碼方式?jīng)Q定的。來看看里面是如何進(jìn)行字符串的操作的:
String encodedString = new String(content.getBytes(), encoding);
char[] charArray = inStr.toCharArray();
可以看到系統(tǒng)首先對原始字符串按照默認(rèn)的編碼方式進(jìn)行編碼,得到一個字節(jié)數(shù)組,然后按照指定的新的編碼方式進(jìn)行解碼,得到新的編碼后的字符串。再轉(zhuǎn)換成對應(yīng)的字符數(shù)組。
由于在中文平臺下,默認(rèn)的字符集編碼是GBK,于是content.getBytes()得到的是什么呢?就是下面這4個字節(jié):
byte[0] = -42 hex string = ffffffd6
byte[1] = -48 hex string = ffffffd0
byte[2] = -50 hex string = ffffffce
byte[3] = -60 hex string = ffffffc4
如果新的encoding是GBK,那么經(jīng)過解碼后,由于一個字符用2個字節(jié)表示。于是最終的結(jié)果就是:
char[0]='中' --- byte[0] + byte[1]
char[1]='文' --- byte[2] + byte[3]
如果新的encoding是ISO-8859-1,那么經(jīng)過解碼后,由于一個字符用1個字節(jié)表示,于是原來本應(yīng)該2個字節(jié)一起解析的變成單個字節(jié)解析,每個字節(jié)都代表了一個漢字字符的一半。這一半的字節(jié)在ISO-8859-1中找不到對應(yīng)的字符,就變成了"?"了,最終的結(jié)果:
char[0]='?' ---- byte[0]
char[1]='?' ---- byte[1]
char[2]='?' ---- byte[2]
char[3]='?' ---- byte[3]
如果新的encoding是UTF-8,那么經(jīng)過解碼后,由于一個字符用3個字節(jié)表示,于是原來4個字節(jié)的數(shù)據(jù)無法正常的解析成UTF-8的數(shù)據(jù),最終的結(jié)果也是每一個都變成"?"。
char[0]='?' ---- byte[0]
char[1]='?' ---- byte[1]
char[2]='?' ---- byte[2]
char[3]='?' ---- byte[3]
如果是在英文平臺下,由于默認(rèn)的編碼方式是Cp1252,于是content.getBytes()得到的字節(jié)都是被截去一半的殘留字符,所以我們看到在英文平臺下,不論指定的encoding是GBK、UTF-8,其結(jié)果和ISO-8859-1都是一樣的。
記住:
這個方法再次證明了String的getBytes()方法的危險性,如果我們使用new String(str.getBytes(), encoding)對字符串進(jìn)行重新編碼解碼時,我們一定要清楚str.getBytes()方法返回的字節(jié)數(shù)組的長度、內(nèi)容到底是什么,因?yàn)樵诮酉聛硎褂眯碌膃ncoding進(jìn)行編碼解碼時,Java并不會自動地對字節(jié)數(shù)組進(jìn)行擴(kuò)展以適應(yīng)新的encoding。而是按照新的編碼方法直接對該字節(jié)數(shù)組進(jìn)行解析。
于是結(jié)果就像上面的例子一樣,同樣是4個原始字節(jié),有些每2個一組進(jìn)行解析,有些每個一組進(jìn)行解析,有些每3個一組進(jìn)行解析。其結(jié)果就只能看那種編碼方式合適了。
【結(jié)論】
FileWriter是字符流輸出流,而OutputStreamWriter是字節(jié)流輸出流
①在中文平臺下,如果使用FileWriter,不論你如何設(shè)置字符集都不會起作用。因?yàn)樗捎玫氖悄J(rèn)的系統(tǒng)字符集。即便你設(shè)置了System.setProperty("file.encoding", "ISO-8859-1"),或者在運(yùn)行時給予參數(shù)-Dfile.encoding=UTF-8都不會起作用。你會發(fā)現(xiàn)它最終還是都已"GB2312"或者"GBK"的方式保存。
在中文平臺下,如果使用OutputStreamWriter,則在后臺寫入時會把字符流轉(zhuǎn)換成字節(jié)流,此時指定的編碼字符集就起作用了。可以看到在指定GBK、UTF-8的情況下中文可以正常的保存和讀取,同時文件按照我們給定的方式保存了。而對于ISO-8859-1則變成了?,這再次證明了采用ISO-8859-1是不能保存中文的,而且會因?yàn)橹形木幋a在ISO-8859-1的編碼中找不到對應(yīng)的字符而默認(rèn)轉(zhuǎn)換成?。
②在英文平臺下,如果使用FileWriter,不論你如何設(shè)置字符集同樣都不會起作用。所有的文件都將按照ISO-8859-1的編碼方式保存,毫無疑問地變成了?。在英文平臺下,如果使用OutputStreamWriter,則只有當(dāng)我們把字符和文件的編碼方式正確設(shè)置為GBK、UTF-8的情況下,中文才能正確的保存并顯示。
③通過上述的實(shí)驗(yàn)證明,為了確保在不同的平臺下,客戶端輸入的中文可以被正確地解析、保存、讀取。最好的辦法就是使用OutputStreamWriter配合UTF-8編碼。
如果不想使用UTF-8編碼,那么可以考慮使用GB2312,不建議使用GBK、GB18030。因?yàn)閷τ谀承├鲜降奈谋揪庉嬈鳎踔敛恢С諫BK、GB18030的編碼,但是對于GB2312則是一定支持的。因?yàn)榍皟烧叨疾皇菄鴺?biāo)但后者是。
④關(guān)于String的getBytes(),getBytes(encoding)和new String(bytes, encoding)這三個方法,非常值得注意:
A.getBytes():使用平臺默認(rèn)的編碼方式(通過file.encoding屬性獲取)方式來將字符串轉(zhuǎn)換成byte[]。得到的是字符串最原始的字節(jié)編碼值。
B.getBytes(NAME_OF_CHARSET):使用指定的編碼方式將字符串轉(zhuǎn)換成byte[],如果想要得到正確的字節(jié)數(shù)組,程序員必須給出正確的NAME_OF_CHARSET。否則得到的就不會得到正確的結(jié)果。
C.new String(bytes, encoding):如果我們在客戶端使用UTF-8編碼的JSP頁面發(fā)出請求,瀏覽器編碼后的UTF-8字節(jié)會以ISO-8859-1的形式傳遞到服務(wù)器端。所以要得到經(jīng)HTTP協(xié)議傳輸?shù)脑甲止?jié),我們需要先調(diào)用getBytes("ISO-8859-1")得到原始的字節(jié),但由于我們客戶端的原始編碼是UTF-8,如果繼續(xù)按照ISO-8859-1解碼,那么得到的將不是一個中文字符,而是3個亂碼的字符。所以我們需要再次調(diào)用new String(bytes,"UTF-8"),將字節(jié)數(shù)組按照UTF-8的格式,每3個一組進(jìn)行解碼,才能還原為客戶端的原始字符。
D.String的getBytes()、getBytes(NAME_OF_CHARSET)方法都是比較微妙的方法,原則上:傳輸時采用的是什么編碼,我們就需要按照這種編碼得到字節(jié)。new String(bytes, NAME_OF_CHARSET)則更加需要小心,原則上:客戶端采用的是什么編碼,那么這里的NAME_OF_CHARSET就必須和客戶端保持一致。
例如JSP頁面是GBK,那么我們接收頁面?zhèn)鬟f而來的參數(shù)時就必須使用new String(parameter.getBytes("ISO-8859-1"), "GBK");如果使用了錯誤的解碼方式,如使用了UTF-8,那么得到的很有可能就是亂碼了。
也就是說:GBK---ISO-8859-1---GBK、UTF-8---ISO-8859-1---UTF-8的轉(zhuǎn)換過程是沒有問題的。但是GBK---ISO-8859-1---UTF-8、UTF-8---ISO-8859-1---GBK的字節(jié)直接轉(zhuǎn)碼則可能導(dǎo)致亂碼,需要另外的轉(zhuǎn)換過程。
記住:
謹(jǐn)慎地使用getBytes(NAME_OF_CHARSET)和new String(bytes, NAME_OF_CHARSET),除非你很清楚的知道原始的字符編碼和傳輸協(xié)議使用的編碼。
推薦使用基于服務(wù)器的配置、過濾器設(shè)置request/response的characterEncoding、content type屬性。還有就是JSP頁面的pageEncoding屬性、HTML meta元素的content type屬性。盡量避免頻繁的在代碼中進(jìn)行字符串轉(zhuǎn)碼,即降低了效率又增加了風(fēng)險。
java編碼
//我寫了個fixString方法可以把s,轉(zhuǎn)化成漢字,然后你在比較,不就可以了
public class t {
public static void main(String[] args) {
String s = "%u4e2d%u56fd";// “中國”的Unicode編碼
s = s.replaceAll("%", "\\\\");
System.out.println("s=" + s);// 結(jié)果是s=\u4e2d\u56fd
String s2 = "\u4e2d\u56fd";
System.out.println("s2=" + s2);// 結(jié)果是“s2=中國”
System.out.println(fixString(s).equals(s2));
}
static String fixString(String s) {
while (true) {
int index = s.indexOf("\\u");
if (index != -1) {
String s1 = s.substring(index, index + 6);
if (s1.matches("\\\\u[0-9A-Fa-f]{4}")) {
char c = (char) Integer.parseInt(s1.replace("\\u", ""), 16);
s = s.substring(0, index) + c + s.substring(index + 6);
}
} else {
break;
}
}
return s;
}
}
求助,java代碼怎么實(shí)現(xiàn)把html的編碼格式從gb2312轉(zhuǎn)換為UTF-8
Java中字符串轉(zhuǎn)碼,根據(jù)實(shí)際運(yùn)用的環(huán)境有以下三種方式
使用Java.lang.String這是最常用的方法,先用對應(yīng)編碼獲取字節(jié),然后重新構(gòu)造新編碼,示例代碼如下:String?s?=?"清山";??
byte[]?b?=?s.getBytes("utf-8");//編碼??
String?sa?=?new?String(b,?"gb2312");//解碼:用什么字符集編碼就用什么字符集解碼
java.io.InputStreamReader/OutputStreamWriter:橋轉(zhuǎn)換讀寫文件的應(yīng)用中,可以使用這種方式,直接在IO流構(gòu)造中轉(zhuǎn)換,示例代碼如下:
InputStream?is?=?new?FileInputStream("C:/項(xiàng)目進(jìn)度跟蹤.txt");//文件讀取??
InputStreamReader?isr?=?new?InputStreamReader(is,?"utf-8");//解碼??
OutputStream?os?=?new?FileOutputStream("C:/項(xiàng)目進(jìn)度跟蹤_gb2312.txt");//文件輸出??
OutputStreamWriter?osw?=?new?OutputStreamWriter(os,?"gb2312");//開始編碼
java.nio.Charset使用nio中的Charset轉(zhuǎn)換字符,示例代碼如下:Charset?inSet?=?Charset.forName("utf-8");??//?解碼字符集?
Charset?outSet?=?Charset.forName("gb2312");??//?編碼字符集??
CharsetDecoder?de?=?inSet.newDecoder();??//?解碼器
CharsetEncoder?en?=?outSet.newEncoder();//?編碼
分享標(biāo)題:java字符編碼實(shí)例代碼 java字符編碼表
本文鏈接:http://www.ef60e0e.cn/article/dojgded.html