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 中文 亂碼問題Java
- Java 解決中文亂碼問題Java
- Java,MySQL中文亂碼問題求教JavaMySql
- java處理中文亂碼問題Java
- Java Web開發中文亂碼問題JavaWeb
- java中解決request中文亂碼問題Java
- EasyUI 中文亂碼問題UI
- MSSQL中文亂碼問題SQL
- Java讀取文字檔案中文亂碼問題Java
- SpringMVC中文亂碼問題SpringMVC
- Python中文亂碼問題Python
- Cookie值中文亂碼問題Cookie
- 解決中文亂碼問題
- Python BeautifulSoup中文亂碼問題Python
- MySql中文亂碼問題解決MySql
- Jmeter 解決中文亂碼問題JMeter
- RDSSQLSERVER解決中文亂碼問題SQLServer
- 解決MySQL中文亂碼問題MySql
- ubuntu 中文顯示亂碼問題Ubuntu
- vscode中文亂碼問題VSCode
- 解決plsql中中文亂碼問題SQL
- 關於中文亂碼問題(總結)
- MySQL客戶端中文亂碼問題。MySql客戶端
- BIP輸出PDF中文亂碼問題
- Ruby On Rails實踐—中文亂碼問題AI
- Ubuntu 字元介面中文亂碼問題Ubuntu字元
- Navicat for mysql 顯示中文亂碼問題MySql
- springmvc 解決中文亂碼問題SpringMVC
- js解決url中文亂碼問題JS
- java web 中文亂碼JavaWeb
- 深入分析 Java 中的中文編碼問題Java
- Java 中的中文編碼問題深入分析Java
- 如何解決PuTTY中文亂碼的問題
- python查詢mysql中文亂碼問題PythonMySql
- idea控制檯中文亂碼的問題Idea
- SpringMvc解決Restful中文亂碼問題SpringMVCREST
- 徹底搞懂 python 中文亂碼問題Python
- mysql操作命令梳理(4)-中文亂碼問題MySql