做軟件開發的同學不論是新手還是那些老鳥都經常會遇到各種各樣的亂碼問題,本文章就這些亂碼問題做一個簡單的分析,以幫助大家去理解、處理這些問題。下邊分兩種情況去分析這種問題。
一、每種軟件的默認編碼方式不同
1、記事本
記事本是大家常用的軟件,也許你會經常聽別人說記事本是無編碼的,可是你明白記事本為什麼是沒有編碼的嗎?
其實是這樣的,記事本確實是沒有編碼方式的,也就是說記事本你寫進去什麼內容它(記事本)就顯示什麼內容,這裡需要注意的是你寫入的內容就是顯示的內容,根本原因是因為記事本沒有默認的編碼方式。
2、EXCEL
EXCEL有自己默認的編碼方式(ASCII),注意這裡要區分上邊的記事本,正因為類似EXCEL這樣的軟件有默認編碼,所以才會產生亂碼問題。例如:你用程序往EXCEL中寫入UTF-8格式的內容,而你默認打開該EXCEL時它會用ASCII的格式打開,這時用ASCII去讀取UTF-8寫入的內容就會出現亂碼。
二、寫入編碼格式和讀取編碼格式不同
為什麼要把【每種軟件的默認編碼方式不同】寫在第一條呢,其實這樣是想讓大家理解不同軟件的默認編碼方式不同(覺得自己說的這些有點啰嗦),這裡要引入的是浏覽器,浏覽器也是一種軟件,也有自己的默認編碼方式。下邊再分兩種情況去介紹。
1、頁面訪問亂碼
如果服務器傳回的頁面(文件)有編碼方式(例如:UTF-8),而頁面中這時又沒有指定文件內容的編碼方式,這時浏覽器就會按照自己的默認編碼方式(例如:GBK)去讀這個UTF-8文件,這時就會產生亂碼情況。解決方式就是在該頁面文件中指定編碼方式。
2、文件下載時名稱亂碼
大家做文件下載時經常會遇到文件名稱亂碼的情況,項目中指定的全局的編碼方式,頁面中同樣也指定了相同的編碼方式,可是為什麼還是會亂碼呢,這是因為文件下載時會自動用浏覽器的默認編碼方式(GB系列)去讀取你往浏覽器傳回的文件名稱(往往是UTF-8),所以亂碼就產生了,文件下載不同與頁面,所以你指定頁面的編碼方式在這裡是不起作用的,解決方式就是把文件名稱用GB系列編碼方式編碼。
3、文件下載時內容亂碼
這裡舉一個容易出錯的例子,大家生成一個CSV文件傳回到客戶端(用流的方式)後,在客戶端用EXCEL打開這個CSV文件,往往發現裡邊的內容是亂碼的,這時不論你再後台程序中怎麼調試,怎麼設置編碼它都是亂碼的。亂碼的根本原因就是EXCEL是有默認編碼方式的(ASCII),這裡要區分下,EXCELL可以自動識別編碼方式,但識別有沒有一個標准的類型,而我們的後台應用往往是UTF-8(無BOM(Byte Order Mark))(至於BOM不理解的大家問度娘吧),而EXCEL是用UTF-8(有BOM)方式去讀取。解決方法就是往CSV中寫入內容時就寫入有BOM標識的UTF-8格式:
OutputStreamWriter osw = new OutputStreamWriter(resp.getOutputStream(), "UTF-8"); // 要輸出的內容 result = (String)contentMap.get(RESPONSE_RESULT); resp.setHeader("Content-Disposition", "attachment;filename=test.csv"); osw.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF })); osw.write(result); osw.flush();