首頁 > Java > java教程 > java io亂碼怎麼辦

java io亂碼怎麼辦

藏色散人
發布: 2020-05-21 10:52:02
原創
2693 人瀏覽過

java io亂碼怎麼辦

java io亂碼怎麼辦? java中IO及中文亂碼問題

第一次發這種博客,所以一直在糾結怎麼開頭,乾脆直奔主題吧,把自己的一些總結體會記錄下來,先從簡單的學習開始,希望可以慢慢堅持,以後的內容可以寫的更好更有意義。

其實真正在工作中中文亂碼的問題遇到的不多,那是因為公司為了開發方便所以文件都統一編碼了。但是我覺得還有很有必要去稍微了解一下其原理的。

推薦:《java學習

IO就是輸入輸出流,用物件導向來理解的話,就是輸入,輸出流對象,主要用來操作文件物件。所以再稍微談談文件的概念,即File物件。在Java中,File不是我們平常生活中指的某個具體文件,而是某個路徑對象,比如說File file=new File("D:\\aaa"); 這是一個File對象,也許它表示的是一個資料夾,也許這個路徑都不存在,但這句程式碼就的確確建立了一個表示該路徑的File物件。這種寫法只是不常用罷了。因為我們平常可能更多的是操作一個文本,圖片等等,如File f=new File("aaa.txt");

上面簡單說了IO,File是什麼,接下來再談談這些圖片,文字,影片等資訊是如何保存在我們儲存裝置上的。

個人理解是不管是什麼類型的文件,都是二進位的形式保存,最小單位是1個byte,即8位01組成。所以說我們假如要拷貝一個文件,只要操作位元組流就好了,即把一個文件中的所有字節拿到,寫到另一個文件中就OK了,其實理論上是可以的,但是對於字符型的文件比較特殊。

這也就是為什麼會有中文亂碼的問題出現。 ASCII碼表大家都很熟悉,起碼都聽說過,它應該算是很早出現的一種碼表了吧,起初只是用來表示26個英文字母和一些特殊符號(因為計算機只識別二進制,所以要把字元用對應的位元組來代替,形成一張碼表)。

但隨著電腦的發展,ASCII應該不夠用了吧,而且很多國家應該也都有自己的一套編碼方案,所以就出現了不同的編碼表。常見的有GBK,UTF-8,而jvm中預設使用的是unicode編碼,即以2個位元組表示一個漢字,UTF-8則不一定,可能3個位元組表示一個漢字,也可能更多。所以就出現了一個問題,同一個漢字在不同的碼表中對應的字節碼的個數和內容都不相同。

所以要如何解決?

我們從A磁碟上拷貝一張圖片到B磁碟上,只要把A的所有位元組拿到B就可以了。但是同樣的方式操作一個文字其實也是可以的,前提是A和B中的文字編碼要相同。因為圖片不存在位元組編碼的問題。但是我要從網路上或伺服器去傳輸中文怎麼辦呢,肯定不能單單通過字節來實現了(因為我們不可能遇到問題就手動去更改文件的編碼方式吧)。所以java提供了字元流對象,也就是在位元組流的基礎上加上對編碼的設置,達到解決亂碼的問題。

廢話不多說,用幾個小案例來說明一下:

1,先在目前專案下新建aa.txt,bb.txt。隨便在aa中寫幾個中文字。會發現這兩種方式都可以實現

a,採用字元流

FileReader fr=new FileReader("aa.txt");
FileWriter fw=new FileWriter("bb.txt");
  int c;
  while((c=fr.read())!=-1){
   fw.write(c);
  }
  fr.close();
  fw.close();
登入後複製

b,採用位元組流

FileInputStream fis=new FileInputStream("aa.txt");
FileOutputStream fos=new FileOutputStream("bb.txt");
  int b;
  while((b=fis.read())!=-1){
   fos.write(b);
  }
  fis.close();
  fos.close();
登入後複製

2,此時假如aa的編碼方式是UTF-8的話,那我們把bb的編碼改為GBK看看,同樣運行上面兩種方法,全部亂碼。

原因就是因為兩個檔案的編碼方式不同,導致中文查的碼表不同,所以亂碼。

3,所以當兩邊檔案的編碼方式不同,我們可以在讀取和寫入的時候都指定與其檔案對應的編碼即可。

實作方式如下:

InputStreamReader isr=new InputStreamReader(new FileInputStream("aa.txt"),"utf-8");
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("bb.txt"),"gbk");
  char[] arr=new char[1024];
  int len;
  while((len=isr.read(arr))!=-1){
   String s=new String(arr,0,len);
   System.out.println(s);
   osw.write(s);
  }
  isr.close();
  osw.close();
登入後複製

程式碼雖然很簡單,還是簡單的解釋一下,從API可以發現InputStreamReader和OutputStreamWriter都是操作字元的對象,繼續Reader和Writer。

主要用來把位元組轉成字符,字符轉成字節。所以從構造也可以發現,傳入的是位元組流物件。以utf-8去讀取位元組流轉成字符,然後將字符以gbk編碼轉成位元組寫入。

下面幾行就不做解釋了,都是基礎裡面的方法。構造中傳入的是匿名內部類別對象,還有裝飾設計模式,這種寫法簡單了解下即可。

關於位元組流和字元流其實還有很多很好用的類,像是BufferedInputStream,BufferedReader等等,再次不做贅述。

關於jvm和系統平台的編碼問題,在次不做解釋。

可以用String來嘗試一下,觀察字串在編譯和執行時的字節碼及編碼問題。

以上是java io亂碼怎麼辦的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板