最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java中的編碼轉(zhuǎn)換過程(以utf8和gbk為例)

 更新時間:2023年04月13日 10:14:46   作者:請叫我徐先生  
這篇文章主要介紹了java中的編碼轉(zhuǎn)換過程(以utf8和gbk為例),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

java中的編碼轉(zhuǎn)換(以utf8和gbk為例)

在正常javaweb開發(fā)中經(jīng)常會發(fā)現(xiàn)字符轉(zhuǎn)換的需求,會存在中文字符轉(zhuǎn)換亂碼的現(xiàn)象,如何解決以及其轉(zhuǎn)換原理我至今懵懵懂懂,于是專門寫了個測試代碼進(jìn)行嘗試,總算理清了編碼,先上結(jié)論,總結(jié)如下:

utf8中存放有各種語言編碼,當(dāng)前主流開發(fā)中會使用utf8進(jìn)行編碼解碼,該方式不會產(chǎn)生亂碼,產(chǎn)生亂碼有以下幾種情況

  • 1、gbk(中文)、iso-8859-1(無中文)等其他方式進(jìn)行編碼,則只能用其對應(yīng)方式進(jìn)行解碼,否則為亂碼
  • 2、使用utf8進(jìn)行編碼用其他方式解碼則會導(dǎo)致亂碼,需進(jìn)行一次轉(zhuǎn)換
  • 3、使用無對應(yīng)字符(中文)的字符集(iso-8859-1)編碼會導(dǎo)致亂碼,且無法還原解碼

以下是針對以上情況的代碼測試

1.如何編碼就如何解碼

/**
?* 測試編碼轉(zhuǎn)換 中文 => utf-8 編碼 - 解碼
?*/
@Test
public void test0() {
? ? String test = "測試";
? ? System.out.println(Arrays.toString(test.getBytes(StandardCharsets.UTF_8)));//[-26, -75, -117, -24, -81, -107]
? ? System.out.println(new String(test.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8));//測試
}
/**
?* 測試編碼轉(zhuǎn)換 中文 => gbk 編碼 - 解碼
?*/
@Test
public void test1() throws UnsupportedEncodingException {
? ? String test = "測試";
? ? System.out.println(Arrays.toString(test.getBytes("gbk")));//[-78, -30, -54, -44]
? ? System.out.println(new String(test.getBytes("gbk"), "GBK"));//測試
}

utf8編碼 - 錯誤形式解碼

/**
?* 測試編碼轉(zhuǎn)換 中文 => utf-8 編碼- gbk解碼
?*/
@Test
public void test2() throws UnsupportedEncodingException {
? ? String test = "測試";
? ? System.out.println(Arrays.toString(test.getBytes(StandardCharsets.UTF_8)));//[-26, -75, -117, -24, -81, -107]
? ? System.out.println(new String(test.getBytes(StandardCharsets.UTF_8), "gbk"));//嫻嬭瘯
}

正確做法,按錯誤的解碼形式(gbk)作為中轉(zhuǎn),將其按錯誤形式(gbk)重新還原編碼(utf8-encode),再使用utf8進(jìn)行一次正確解碼(utf8-decode)即可得到原來的字符

/**
?* 測試編碼轉(zhuǎn)換 中文 => utf-8 編碼 - gbk 解碼 ===> gbk 編碼 - utf-8解碼
?* "測試" => (utf8-encode)[-26, -75, -117, -24, -81, -107] => (gbk-decode)嫻嬭瘯
?* "嫻嬭瘯" => (utf8-encode)[-26, -75, -117, -24, -81, -107] => (utf8-decode)"測試"
?*/
@Test
public void test3() throws UnsupportedEncodingException {
? ? String test = "測試";
? ? String test_gbk_utf8 = new String(test.getBytes(StandardCharsets.UTF_8), "gbk");
? ? System.out.println(test_gbk_utf8);//嫻嬭瘯
? ? String test_utf8_gbk = new String(test_gbk_utf8.getBytes("gbk"), StandardCharsets.UTF_8);
? ? System.out.println(test_utf8_gbk);//測試

}

3.無對應(yīng)字符編碼

@Test
? ? public void test4() throws UnsupportedEncodingException {
? ? ? ? String test = "測試";
? ? ? ? System.out.println(Arrays.toString(test.getBytes(StandardCharsets.ISO_8859_1)));//[63, 63]
? ? ? ? System.out.println(new String(test.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.ISO_8859_1));//??
? ? }

該情況下即使使用原先的編碼方式進(jìn)行解碼也無法還原字符了,屬于不可逆的狀態(tài)

java編碼格式的轉(zhuǎn)換以及亂碼恢復(fù)

如何在java中進(jìn)行編碼格式轉(zhuǎn)換

下面這行代碼的含義是: 獲取目標(biāo)字符串str的gbk編碼格式的二進(jìn)制碼,然后將二進(jìn)制碼按照utf8編碼格式重新編碼成字符串,當(dāng)然,下面這種寫法百分百會亂碼,因?yàn)榫幋a格式不一致.

new String(str.getBytes("gbk"),"utf8")

首先什么情況會亂碼

如果要傳輸一個字符串,首先要按照一定的編碼格式將字符串轉(zhuǎn)換成字節(jié)流,當(dāng)字節(jié)流傳輸?shù)浇邮辗降臅r候再將字節(jié)流按照某種編碼格式轉(zhuǎn)換成字符串.亂碼也正是產(chǎn)生在重新轉(zhuǎn)換成字符串的過程中.以下是我對中文亂碼的測試:

? String str="彩虹";
? ? ? ? String [] a=new String[] {"gbk","unicode","utf8","gb2312"};
? ? ? ? for (int i=0;i<a.length;i++){
? ? ? ? ? ? for (int j=0;j<a.length;j++){
? ? ? ? ? ? ? ? System.out.println("二進(jìn)制格式: ? "+a[i]+"編碼格式: ?"+a[j]);
? ? ? ? ? ? ? ? System.out.println("編碼后的字符串: ?"+new String(str.getBytes(a[i]),a[j]));
?
? ? ? ? ? ? }
? ? ? ? }

二進(jìn)制格式:   gbk編碼格式:  gbk
編碼后的字符串:  彩虹
二進(jìn)制格式:   gbk編碼格式:  unicode
編碼后的字符串:  ??
二進(jìn)制格式:   gbk編碼格式:  utf8
編碼后的字符串:  ???
二進(jìn)制格式:   gbk編碼格式:  gb2312
編碼后的字符串:  彩虹
二進(jìn)制格式:   unicode編碼格式:  gbk
編碼后的字符串:  ?_i唝
二進(jìn)制格式:   unicode編碼格式:  unicode
編碼后的字符串:  彩虹
二進(jìn)制格式:   unicode編碼格式:  utf8
編碼后的字符串:  ??_i?y
二進(jìn)制格式:   unicode編碼格式:  gb2312
編碼后的字符串:  ??_i?y
二進(jìn)制格式:   utf8編碼格式:  gbk
編碼后的字符串:  褰╄櫣
二進(jìn)制格式:   utf8編碼格式:  unicode
編碼后的字符串:  ?馹
二進(jìn)制格式:   utf8編碼格式:  utf8
編碼后的字符串:  彩虹
二進(jìn)制格式:   utf8編碼格式:  gb2312
編碼后的字符串:  褰╄??
二進(jìn)制格式:   gb2312編碼格式:  gbk
編碼后的字符串:  彩虹
二進(jìn)制格式:   gb2312編碼格式:  unicode
編碼后的字符串:  ??
二進(jìn)制格式:   gb2312編碼格式:  utf8
編碼后的字符串:  ???
二進(jìn)制格式:   gb2312編碼格式:  gb2312
編碼后的字符串:  彩虹

可以看出,如果二進(jìn)制編碼格式和字符串的編碼格式不同就會引起亂碼.

為什么gbk,gb2312轉(zhuǎn)換沒有亂碼?

gbk和gb2312之間的轉(zhuǎn)換沒有亂碼是因?yàn)間bk是gb2312的增強(qiáng)版本,支持更多的漢字編碼,所以如果二進(jìn)制編碼格式是gbk而解碼格式是gb2312,這種情況是有可能出現(xiàn)部分漢字亂碼的.

亂碼的數(shù)據(jù)可以轉(zhuǎn)變回來嗎?

上述結(jié)果中的亂碼其實(shí)可以大致分為兩種,一種是復(fù)雜的漢字和圖形組合,一種是"?".

如果希望恢復(fù)的亂碼數(shù)據(jù)中有問號,那么這條數(shù)據(jù)恢復(fù)的可能性就不大了.因?yàn)槌?quot;?"的其他亂碼其實(shí)都是有自己的編碼規(guī)則的,只要逆向的解碼并按照正確的編碼格式重新編碼就可以恢復(fù).但是"?"除外,因?yàn)楫?dāng)字節(jié)流按照某種編碼格式重新編譯的時候,字節(jié)數(shù)據(jù)中無法按照該編碼格式轉(zhuǎn)換成有意義字符的字節(jié)都會轉(zhuǎn)換成"?",所以就算逆向的編碼成字節(jié)流,所有的"?"都會轉(zhuǎn)換成同一字節(jié),也就失去了他本身的意義.

如果亂碼中不包含"?",那么還是有希望轉(zhuǎn)換回去的,我以上述亂碼中的 "褰╄櫣" 為例重新進(jìn)行了一次轉(zhuǎn)換,代碼如下:

? ? ? ?String str="褰╄櫣";
? ? ? ? String [] charset=new String[] {"gbk","unicode","utf8","gb2312"};
? ? ? ? for (int i=0;i<charset.length;i++){
? ? ? ? ? ? for (int j=0;j<charset.length;j++){
? ? ? ? ? ? ? ? System.out.println("二進(jìn)制格式: ? "+charset[i]+"編碼格式: ?"+charset[j]);
? ? ? ? ? ? ? ? System.out.println("編碼后的字符串: ?"+new String(str.getBytes(charset[i]),charset[j]));
?
? ? ? ? ? ? }
? ? ? ? }

二進(jìn)制格式:   gbk編碼格式:  gbk
編碼后的字符串:  褰╄櫣
二進(jìn)制格式:   gbk編碼格式:  unicode
編碼后的字符串:  ?馹
二進(jìn)制格式:   gbk編碼格式:  utf8
編碼后的字符串:  彩虹
二進(jìn)制格式:   gbk編碼格式:  gb2312
編碼后的字符串:  褰╄??
二進(jìn)制格式:   unicode編碼格式:  gbk
編碼后的字符串:  ??0%Dj?
二進(jìn)制格式:   unicode編碼格式:  unicode
編碼后的字符串:  褰╄櫣
二進(jìn)制格式:   unicode編碼格式:  utf8
編碼后的字符串:  ???0%Dj?
二進(jìn)制格式:   unicode編碼格式:  gb2312
編碼后的字符串:  ???0%Dj?
二進(jìn)制格式:   utf8編碼格式:  gbk
編碼后的字符串:  瑜扳晞婭?
二進(jìn)制格式:   utf8編碼格式:  unicode
編碼后的字符串:  ??閄?
二進(jìn)制格式:   utf8編碼格式:  utf8
編碼后的字符串:  褰╄櫣
二進(jìn)制格式:   utf8編碼格式:  gb2312
編碼后的字符串:  瑜扳??婭?
二進(jìn)制格式:   gb2312編碼格式:  gbk
編碼后的字符串:  褰╄?
二進(jìn)制格式:   gb2312編碼格式:  unicode
編碼后的字符串:  ??
二進(jìn)制格式:   gb2312編碼格式:  utf8
編碼后的字符串:  彩??
二進(jìn)制格式:   gb2312編碼格式:  gb2312
編碼后的字符串:  褰╄?

可以看到 其中一種轉(zhuǎn)換方式成功的將亂碼轉(zhuǎn)變回了正常的中文漢字

二進(jìn)制格式:   gbk編碼格式:  utf8
編碼后的字符串:  彩虹

總結(jié)

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java實(shí)現(xiàn)上傳和下載工具類

    java實(shí)現(xiàn)上傳和下載工具類

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)上傳和下載工具類,文件上傳到ftp服務(wù)工具類,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 聊聊Java 成員變量賦值和構(gòu)造方法誰先執(zhí)行的問題

    聊聊Java 成員變量賦值和構(gòu)造方法誰先執(zhí)行的問題

    這篇文章主要介紹了聊聊Java 成員變量賦值和構(gòu)造方法誰先執(zhí)行的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Java C++題解leetcode816模糊坐標(biāo)示例

    Java C++題解leetcode816模糊坐標(biāo)示例

    這篇文章主要為大家介紹了Java C++題解leetcode816模糊坐標(biāo)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Java 工具類總結(jié)目錄(分享)

    Java 工具類總結(jié)目錄(分享)

    下面小編就為大家?guī)硪黄狫ava 工具類總結(jié)目錄(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • SpringMVC xml文件路徑在web.xml中的配置方式

    SpringMVC xml文件路徑在web.xml中的配置方式

    這篇文章主要介紹了SpringMVC xml文件路徑在web.xml中的配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java設(shè)計模式之java中介者模式詳解

    Java設(shè)計模式之java中介者模式詳解

    這篇文章主要為大家詳細(xì)介紹了23種設(shè)計模式之java中介者模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-09-09
  • 四步輕松搞定java web每天定時執(zhí)行任務(wù)

    四步輕松搞定java web每天定時執(zhí)行任務(wù)

    本篇文章主要介紹了四步輕松搞定java web每天定時執(zhí)行任務(wù),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Spring三種方法的注解自動注入問題

    Spring三種方法的注解自動注入問題

    這篇文章主要介紹了Spring三種方法的注解自動注入問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • java List.of()與Arrays.asList()方法對比分析

    java List.of()與Arrays.asList()方法對比分析

    這篇文章主要為大家介紹了java List.of()與Arrays.asList()方法對比分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Spring + Spring Boot + MyBatis + MongoDB的整合教程

    Spring + Spring Boot + MyBatis + MongoDB的整合教程

    這篇文章主要給大家介紹了關(guān)于Spring + Spring Boot + MyBatis + MongoDB的整合教程,文中通過圖文以及示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-12-12

最新評論

彭阳县| 大安市| 沈丘县| 安国市| 卓尼县| 河曲县| 武陟县| 大新县| 乐陵市| 衡南县| 华阴市| 大关县| 邻水| 墨竹工卡县| 岳普湖县| 泰宁县| 双鸭山市| 梅河口市| 罗山县| 舒兰市| 岫岩| 保山市| 双桥区| 遂昌县| 万全县| 嘉鱼县| 定南县| 日土县| 广水市| 太白县| 体育| 济源市| 贵南县| 泰州市| 慈溪市| 梁河县| 车险| 密山市| 浦北县| 饶阳县| 金山区|