国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java讀寫文件時的GBK和UTF8轉(zhuǎn)換問題

這篇具有很好參考價值的文章主要介紹了Java讀寫文件時的GBK和UTF8轉(zhuǎn)換問題。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

問題引入

文件中的文本以UTF-8的編碼方式存儲,在Java程序中以GBK的編碼方式從文件中讀入,最后再將讀入的內(nèi)容轉(zhuǎn)換為UTF-8編碼,即UTF-8 --> GBK --> UTF-8。這種操作方式能正確讀入文件中的內(nèi)容嗎?

背景知識

因為本文主要討論不同的編碼之間的轉(zhuǎn)換問題,所以有必要先介紹一下文中會用到的幾種編碼方式。

編碼和解碼

將某個字符映射成計算機能存儲和處理的二進制數(shù)的過程稱為編碼,比如字符A的ASCII編碼為b0100 0001,我們通常用十六進制來表示成0x41;將某個二進制數(shù)映射成人類可讀的字符的過程稱為解碼,編碼的逆過程就是解碼。

UTF-8

UTF-8編碼兼容ASCII編碼,也就是說任何一個ASCII編碼的字符,也是UTF-8編碼的字符。比如字符A的ASCII編碼的十六進制表示為0x41,占1個字節(jié),那么字符A的UTF-8編碼也是0x41,占1個字節(jié)。對于一個漢字來說,需要用三個字節(jié)存儲UTF-8編碼,大家可以通過UTF8在線網(wǎng)站獲得任意字符的UTF-8編碼。

GBK

和UTF-8一樣,GBK也是兼容ASCII編碼的。對于一個漢字來說,需要用兩個字節(jié)存儲GBK編碼,大家可以通過GBK在線網(wǎng)站獲得任意漢字的GBK編碼。

Unicode

和UTF-8一樣,Unicode也是兼容ASCII編碼的。對于一個漢字來說,需要用兩個字節(jié)存儲Unicode編碼,大家可以通過Unicode在線網(wǎng)站獲得任意漢字的Unicode編碼。也可以通過GBK2Unicode在線網(wǎng)站獲得某個GBK編碼對應的Unicode編碼。

實驗與分析

為了回答上面的問題,我編寫了兩種不同的文本內(nèi)容,也就是后面的實驗設置1實驗設置2,以此來看一下對于不同類型的文本內(nèi)容,采用上述方式是否都可以正確的讀取。因為Java中對文本文件的讀取主要有兩種類型:讀入到字符串和讀入到字符數(shù)組,因此我分別實現(xiàn)了這兩種讀取方式,也就是后面的實驗代碼1實驗代碼2,以此來探究不同的讀取方式對實驗結(jié)果是否有影響。

實驗環(huán)境

  • JDK:16
  • OS:Monterey 12.2.1
  • 系統(tǒng)默認編碼:UTF-8

實驗代碼1

//將文件中的內(nèi)容讀入到字符串
try(BufferedReader br = new BufferedReader(new FileReader(fileName, Charset.forName("GBK")))){
    String content = br.readLine();
    byte[] bytes = content.getBytes("GBK");
    String str = new String(bytes, "UTF-8");
    System.out.println(str);
}

實驗代碼2

//將文件中的內(nèi)容讀入到字符數(shù)組
try(Reader reader = new FileReader(fileName, Charset.forName("GBK"))){
    char[] content = new char[2];
    reader.read(content);
    String str = new String(content);
    byte[] bytes = str.getBytes("GBK");
    str = new String(bytes, "UTF-8");
    System.out.println(str);
}

實驗設置1

文件的編碼方式為UTF8,文件的內(nèi)容為:

此設置下,文件中只有一個用UTF-8編碼的漢字。我們知道,在UTF-8編碼下,每個漢字占3個字節(jié),大家可以自行檢查一下文件的大小是否為3字節(jié),以避免因為其它的字符(如空格等)影響復現(xiàn)實驗的效果。

在第一個份代碼中(將文件內(nèi)容讀入到字符串),通過單步調(diào)試可以看到,content的內(nèi)容為浣?,和文件中的內(nèi)容不一樣,而且看起來有點像亂碼。繼續(xù)單步運行,將字符串按照GBK的編碼方式轉(zhuǎn)換為字節(jié)數(shù)組。此處需要指定編碼方式為GBK的原因是,我們從文件中讀取的時候指定了GBK的解碼方式,因此,想要轉(zhuǎn)換成字節(jié)數(shù)組也得按照GBK的方式編碼。完成轉(zhuǎn)換之后,得到的字節(jié)數(shù)組bytes的大小為3?,F(xiàn)在我們已經(jīng)有了GBK編碼之后的字節(jié)數(shù)組bytes了,最后將其按照UFT8的方式解碼成字符串,得到????礃幼游覀儧]能正確的讀取到文本文件的內(nèi)容,下面分析一下原因。

漢字的UTF8編碼可以通過之前提到的在線網(wǎng)站得到,其為e4 bd a0,因為Java程序采用GBK的解碼方式讀取文件,所以當讀到第一個字節(jié)e4時,判斷出還需要再讀一個字節(jié)才能構(gòu)成完整的編碼,因此現(xiàn)在讀入的內(nèi)容是e4 bd,通過在線網(wǎng)站知道它對應于漢字。因為Java程序內(nèi)部采用Unicode編碼存儲字符串,所以需要將轉(zhuǎn)換為Unicode編碼,通過在線網(wǎng)站可知它對應的Unicode編碼為6d 63。要注意,實際上Java程序并不需要先把GBK碼解碼成字符,然后再根據(jù)字符做Unicode編碼,而是直接由GBK碼映射到表示相同字符的Unicode碼。Java程序繼續(xù)讀入第三個字節(jié)a0,同時判斷出a0不是一個合法的GBK編碼,但是此時已經(jīng)讀到文件的末尾了,無法繼續(xù)讀入下一個字節(jié)。對于此種情況,Java會將非法的GBK編碼映射成默認的Unicode碼ff fd,此編碼對應的字符是???梢钥吹?,這種映射具有不可逆性,我們無法從ff fd映射回非法的GBK碼,也就是說,這種映射會改變我們的原始數(shù)據(jù)。分析到這兒,我們應該知道,字符串變量content在內(nèi)存中的實際內(nèi)容為6d 63 ff fd(不去考慮大端小端的問題),共四個字節(jié),表示兩個字符?。

接下來將字符串變量content按照GBK的編碼方式轉(zhuǎn)換成字節(jié)數(shù)組。前面說過,content的內(nèi)容為浣?,首先轉(zhuǎn)換第一個字符,其對應的GBK編碼為e4 bd。接下來轉(zhuǎn)換第二個字符?,很遺憾的是,此字符并沒有被GBK收錄,也就是說這個字符沒有對應的GBK編碼,此種情況下會將其轉(zhuǎn)換為GBK編碼3f,它對應的字符是?。因此,字節(jié)數(shù)組bytes = [e4, bd, 3f]

最后一步將字節(jié)數(shù)組按照UTF-8的方式解碼。當遇到第一個字節(jié)e4時,發(fā)現(xiàn)它不是一個合法的UTF-8編碼,因此繼續(xù)讀入下一個字節(jié),然后發(fā)現(xiàn)e4 bd也不是一個合法的UTF-8編碼,繼續(xù)讀入,發(fā)現(xiàn)e4 bd 3f仍然不是一個合法的編碼,但是已沒有更多的字節(jié)可以讀了。不過UTF-8解碼器發(fā)現(xiàn)e4 bd 3f雖然不是一個合法的編碼,但3f卻是一個合法的UTF-8編碼,它對應于字符?。此時解碼器會選擇將3f解碼為?,而認為e4 bd是一個錯誤的編碼,并將其解碼為默認字符?。因此,最終得到的解碼結(jié)果為??。

以上是對運行實驗代碼1時的分析,也就是將文本內(nèi)容讀入到字符串中的情況。對于將文本內(nèi)容讀入到字符數(shù)組的情況,分析過程和實驗代碼1差不多,只是在某些地方有細微的差別。下面簡要的分析一下運行實驗代碼2時的情況。

文件中存儲的數(shù)據(jù)仍然是e4 bd a0,對e4 bd按照GBK解碼得到,因為Java中的char類型也是和String類型一樣,按照Unicode的編碼方式存儲,對應的Unicode碼為6d 63,所以字符數(shù)組中的第一個字符在內(nèi)存中實際存儲的是6d 63。接下來對a0按照GBK解碼,如前所述,a0不是一個合法的GBK碼,對于此種情況,字符數(shù)組會舍棄非法的編碼,因此字符數(shù)組的第二個字符仍然是默認的00 00。下一步中的將字符數(shù)組變?yōu)樽址哪康氖欠奖戕D(zhuǎn)換為字節(jié)數(shù)組,經(jīng)過轉(zhuǎn)換之后得到的字節(jié)數(shù)組bytes = [e4, bd, 00, 00]。最后一步將字節(jié)數(shù)組按照UTF-8的解碼方式轉(zhuǎn)化成字符串,最終得到的解碼結(jié)果為?。

實驗設置2

文件的編碼方式為UTF8,文件的內(nèi)容為:

你A

首先分析代碼1。文件內(nèi)容你A的UTF-8編碼為e4 bd a0 41,按照GBK解碼得到浣燗,其對應的Unicode碼為6d 63 71 d7。 因為字符串使用Unicode編碼進行存儲,所以content在內(nèi)存中存儲的內(nèi)容為6d 63 71 d7。之后對content按GBK編碼獲得對應的字節(jié)數(shù)組,這就又回到了e4 bd a0 41,即bytes = [e4, bd, a0, 41]。最后對此字節(jié)數(shù)組按UTF-8解碼得到你A

對于代碼2的分析,因為e4 bda0 41都是合法的GBK編碼,所以不存在丟棄數(shù)據(jù)的問題,那么代碼2的分析就和代碼1的分析完全相同。

結(jié)論

文件的編碼方式是什么,在讀取的時候就要指定什么樣的編碼方式。文章來源地址http://www.zghlxwxcb.cn/news/detail-469995.html

到了這里,關于Java讀寫文件時的GBK和UTF8轉(zhuǎn)換問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • dedecms編碼轉(zhuǎn)換方法 gbk轉(zhuǎn)UTF-8,UTF-8轉(zhuǎn)GBK(推薦)

    經(jīng)常遇到編碼轉(zhuǎn)換的問題,有的是購買了模板但是模板編碼與程序編碼不符,導致出現(xiàn)亂碼.今天小編給大家分享一篇教程幫助大家解決如何轉(zhuǎn)換模板文件的編碼和程序的編碼問題,一起看看吧! 1.如何轉(zhuǎn)換模板文件編碼? 首先下載一個編碼轉(zhuǎn)換軟件 51EC模板轉(zhuǎn)碼專用工具v1.0免費

    2024年02月03日
    瀏覽(20)
  • JavaScript實現(xiàn)字符編碼轉(zhuǎn)換utf-8/gbk(附完整源碼)

    以上代碼中,我們使用了JavaScript內(nèi)置的TextEncoder和TextDecoder類來實現(xiàn)字符編碼轉(zhuǎn)換。這兩個類是ES6新增的特性,需要在支持ES6的瀏覽器上才能正常運行。 使用示例: 運行結(jié)果說明轉(zhuǎn)換成功。需要注意的是,在不同的瀏覽器中,對字符編碼的支持程度可能不同,因此在使用時需

    2024年02月04日
    瀏覽(54)
  • 徹底解決Qt中文亂碼以及漢字編碼的問題(UTF-8/GBK)

    徹底解決Qt中文亂碼以及漢字編碼的問題(UTF-8/GBK)

    原文鏈接: 這篇文章有點長,內(nèi)容有點多,如果時間急迫,可以直接翻頁去末尾看結(jié)論。紅色字體加粗的。 1、cpp或h文件從window上傳到Ubuntu后會顯示亂碼, 原因是因為ubuntu環(huán)境設置默認是utf-8,Windows默認都是GBK. 我們使用的Windows系統(tǒng)本地字符集編碼為GBK。 2、Windows環(huán)境下,Qt C

    2024年02月05日
    瀏覽(28)
  • Mysql導入sql文件報COLLATION ‘utf8_general_ci‘ is not valid for CHARACTER SET ‘utf8mb4‘原因

    這個錯誤通常是因為MySQL數(shù)據(jù)庫版本較舊,不支持使用 utf8mb4 字符集,而使用了 utf8mb4 字符集的 COLLATION 排序規(guī)則。 utf8mb4 字符集支持存儲更多的字符,包括一些表情符號等,而 utf8 字符集則不支持。如果MySQL版本不支持 utf8mb4 字符集,就會出現(xiàn)以上錯誤。 解決這個問題的方法

    2024年02月13日
    瀏覽(29)
  • 數(shù)據(jù)庫編碼 問題 mysql 修改字符集為utf8mb4

    數(shù)據(jù)庫編碼 問題 mysql 修改字符集為utf8mb4 問題 ; 當向數(shù)據(jù)庫插入表,或者在表中插入數(shù)據(jù)時,出現(xiàn) ERROR 1366 (HY000): Incorrect string value: ‘xBDxF0xD3xB9’ for column ‘name’ at row 1 原因 數(shù)據(jù)庫編碼方式 和 表編碼方式 以及 插入數(shù)據(jù)(字符串)的編碼方式不同 我們可以查看建表,

    2023年04月08日
    瀏覽(31)
  • IDEA連接TiDB報字符集不匹配問題COLLATION ‘utf8_general_ci‘ is not valid for CHARACTER SET ‘utf8mb4‘.

    IDEA連接TiDB報字符集不匹配問題COLLATION ‘utf8_general_ci‘ is not valid for CHARACTER SET ‘utf8mb4‘.

    最近因工作需要,部署了一套TiDB,然而通過IDEA,使用MySQL驅(qū)動連接數(shù)據(jù)庫時,一直報字符集不匹配。網(wǎng)上找了些資料,但是并沒有相關說明。最后請教了一個大佬,問題得到解決。這邊記錄一下,希望能幫助到遇到同樣問題的人。 問題現(xiàn)象 IDEA連接TiDB時,成功連接,但無法

    2024年02月13日
    瀏覽(57)
  • 達蒙數(shù)據(jù)庫:本地編碼:PG_GBK, 導入文件編碼:PG_UTF8錯誤解決

    達蒙數(shù)據(jù)庫:本地編碼:PG_GBK, 導入文件編碼:PG_UTF8錯誤解決

    在windows使用達夢管理工具導入.dmp文件時出現(xiàn)該錯誤 問題解決: 1、找到DM數(shù)據(jù)庫的安裝路徑的bin 目錄下 cmd 進入終端 2、輸入命令行 使用dimp工具進行導入,最后需要加上FULL=Y是表示整個表格導入,但是中間可能會出現(xiàn)報錯

    2024年02月06日
    瀏覽(27)
  • MySQL - 常用排序規(guī)則utf8mb4_general_ci、utf8mb4_unicode_ci、utf8mb4_bin、utf8mb4_0900_ai_ci和存儲字符集 utf8 和 utf8

    MySQL - 常用排序規(guī)則utf8mb4_general_ci、utf8mb4_unicode_ci、utf8mb4_bin、utf8mb4_0900_ai_ci和存儲字符集 utf8 和 utf8

    在創(chuàng)建數(shù)據(jù)庫時,我們經(jīng)常會需要填寫數(shù)據(jù)庫名、字符集、排序規(guī)則 常用的存儲字符集 utf8 和 utf8mb4 排序字符集 utf8mb4_unicode_ci 和 utf8mb4_general_ci、utf8mb4_bin、utf8mb4_0900_ai_ci 1、utf8 utf8 是 Mysql 中的一種字符集,只支持最長三個字節(jié)的 UTF-8 字符,也就是 Unicode 中的基本多文本平

    2024年02月09日
    瀏覽(27)
  • 執(zhí)行SQL文件出現(xiàn)【Unknown collation “utf8mb4_0900_ai_ci”】的解決方案

    執(zhí)行SQL文件出現(xiàn)【Unknown collation “utf8mb4_0900_ai_ci”】的解決方案

    從服務器MySQL中導出數(shù)據(jù)為SQL執(zhí)行腳本后,在本地執(zhí)行導出的SQL腳本。 報錯:Unknown collation “utf8mb4_0900_ai_ci” 打開SQL腳本,查看 utf8mb4_0900_ai_ci ,這是字段的字符集。 1、MySQL 版本不一致。 2、字符集編碼不支持。 1、升級 MySQL 數(shù)據(jù)庫版本 將本地5.7版本的 MySQL數(shù)據(jù)庫升

    2024年02月11日
    瀏覽(30)
  • MySQL常用排序規(guī)則utf8mb4_general_ci、utf8mb4_unicode_ci、utf8mb4_bin、utf8mb4_0900_ai_ci和存儲字符集 utf8 和 utf8mb4

    MySQL常用排序規(guī)則utf8mb4_general_ci、utf8mb4_unicode_ci、utf8mb4_bin、utf8mb4_0900_ai_ci和存儲字符集 utf8 和 utf8mb4

    在創(chuàng)建數(shù)據(jù)庫時,我們經(jīng)常會需要填寫數(shù)據(jù)庫名、字符集、排序規(guī)則; 而本文主要講述常用的存儲字符集 utf8 和 utf8mb4;排序字符集 utf8mb4_unicode_ci 和 utf8mb4_general_ci、utf8mb4_bin、utf8mb4_0900_ai_ci 一般我本人創(chuàng)建創(chuàng)建數(shù)據(jù)庫通常排序規(guī)則都使用utf8mb4_general_ci,因為對特殊字符的順

    2024年01月17日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包