Java GBK 中文亂碼問題分析
在io相關的操作中經常會出現亂碼問題
比如在一個txt檔案中按GBK編碼儲存內容”淘!我喜歡!”
然後用RandomAccessFile類讀取並列印一行。
RandomAccessFile raf = new RandomAccessFile("D://1.txt","r");System.out.print(raf.readLine());
列印結果顯示亂碼:
在網上查詢到加入相關編碼解碼操作後可以解決該問題
RandomAccessFile raf = new RandomAccessFile("D://1.txt","r"); System.out.print(new String(raf.readLine().getBytes("ISO-8859-1"),"gbk"));
問題:
在這個過程中發生了什麼?
要解答這個問題首先要知道編碼和解碼的概念以及產生的原因:
為什麼要編碼
不知道大家有沒有想過一個問題,那就是為什麼要編碼?我們能不能不編碼?要回答這個問題必須要回到計算機是如何表示我們人類能夠理解的符號的,這些符號也就是我們人類使用的語言。由於人類的語言有太多,因而表示這些語言的符號太多,無法用計算機中一個基本的儲存單元—— byte 來表示,因而必須要經過拆分或一些翻譯工作,才能讓計算機能理解。我們可以把計算機能夠理解的語言假定為英語,其它語言要能夠在計算機中使用必須經過一次 翻譯,把它翻譯成英語。這個翻譯的過程就是編碼。所以可以想象只要不是說英語的國家要能夠使用計算機就必須要經過編碼。這看起來有些霸道,但是這就是現 狀,這也和我們國家現在在大力推廣漢語一樣,希望其它國家都會說漢語,以後其它的語言都翻譯成漢語,我們可以把計算機中儲存資訊的最小單位改成漢字,這樣 我們就不存在編碼問題了。
所以總的來說,編碼的原因可以總結為:
1. 計算機中儲存資訊的最小單元是一個位元組即 8 個 bit,所以能表示的字元範圍是 0~255 個。
2. 人類要表示的符號太多,無法用一個位元組來完全表示。
3. 要解決這個矛盾必須需要一個新的資料結構 char,從 char 到 byte 必須編碼。
名詞解釋:
解碼:將byte陣列轉為char陣列。
編碼:將char陣列轉為byte陣列。
計算機儲存的基本單位是byte,但開啟一個檔案時檔案編輯器已經做了解碼的工作。
以下為解碼過程描述
檔案實際儲存的內容是(以下為 16 進位制):
開啟檔案後看到的內容為
需要詳細說明以下程式碼的處理過程
RandomAccessFile raf= new RandomAccessFile("D://1.txt","r");System.out.print(raf.readLine());
首先看一下java.io.RandomAccessFile#readLine方法的原始碼
public final String readLine() throws IOException { StringBuffer input = new StringBuffer(); int c = -1; boolean eol = false; while (!eol) { switch (c = read()) { case -1: case '/n': eol = true; break; case '/r': eol = true; long cur = getFilePointer(); if ((read()) != '/n') { seek(cur); } break; default: input.append((char)c); break; } } if ((c == -1) && (input.length() == 0)) { return null; } return input.toString(); }
主要關注read()部分和(char)c,read()是一個本地方法,作用是從檔案中讀取一個byte位元組。
(char)c是將變數c從byte型別轉換為char型別,這是一個解碼操作。
問題:此處是以什麼格式進行解碼?
解碼格式是ISO-8859-1
raf.readLine()的處理過程如下
那麼
new String(raf.readLine().getBytes("ISO-8859-1"),"gbk")
這行程式碼做了什麼
首先readLine()按行一位元組一位元組地讀取檔案中的資料,並且按ISO-8859-1進行解碼拼成char陣列,然後getBytes(“ISO-8859-1″)對拼成後的char陣列按ISO-8859-1進行編碼獲取byte陣列,最後new String(string,”gbk”)對編碼後的byte陣列用gbk格式進行解碼成char陣列。
參考資料:
遺留問題:
1 、如何避免重複轉碼。
2 、RandomAccessFile的readLine () 效率非常低,如何提高效率。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2310/viewspace-2803730/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java Web開發中文亂碼問題JavaWeb
- vscode中文亂碼問題VSCode
- EasyUI 中文亂碼問題UI
- 解決中文亂碼問題
- Python BeautifulSoup中文亂碼問題Python
- springmvc 解決中文亂碼問題SpringMVC
- MySql中文亂碼問題解決MySql
- Jmeter 解決中文亂碼問題JMeter
- confluence中文顯示亂碼問題
- js解決url中文亂碼問題JS
- python查詢mysql中文亂碼問題PythonMySql
- 解決plsql中中文亂碼問題SQL
- idea控制檯中文亂碼的問題Idea
- 徹底搞懂 python 中文亂碼問題Python
- linux 安裝字型解決JAVA圖形中文亂碼問題LinuxJava
- java web 中文亂碼JavaWeb
- CentOS8中文亂碼問題CentOS
- phantomjs截圖中文亂碼問題解決JS
- 如何解決PuTTY中文亂碼的問題
- 解決zabbix圖形化中文亂碼問題
- LiveCharts中文顯示亂碼問題的解決Echarts
- 解決Url帶中文引數亂碼問題
- python3-csv寫入中文亂碼問題Python
- Sublime Text 3 中文亂碼問題的解決
- python json.dumps中文亂碼問題解決PythonJSON
- requests請求返回內容 中文亂碼問題
- OxyPlot.SkiaSharp中文顯示亂碼的問題
- 雲伺服器中文亂碼問題解決伺服器
- SqlServer資料庫中文亂碼問題解決SQLServer資料庫
- 完美解決jspdf各種中文亂碼問題JS
- 【SSM】WEB專案中的中文亂碼問題SSMWeb
- java中亂碼問題解決方法Java
- java,awt,中文方框,中文亂碼10/16Java
- java httpclient傳送中文亂碼JavaHTTPclient
- 二進位制修復中文亂碼的問題
- SAP UI5 應用的中文亂碼問題UI
- Mysql中文亂碼問題的最佳解決方法MySql
- 如何解決表單提交的中文亂碼問題