天天看點

java 位元組流與字元流的差別

簡單明了解釋java位元組流和字元流差別

轉自http://blog.csdn.net/cynhafa/article/details/6882061

位元組流與和字元流的使用非常相似,兩者除了操作代碼上的不同之外,是否還有其他的不同呢?

實際上位元組流在操作時本身不會用到緩沖區(記憶體),是檔案本身直接操作的,而字元流在操作時使用了緩沖區,通過緩沖區再操作檔案,如圖12-6所示。

java 位元組流與字元流的差別

下面以兩個寫檔案的操作為主進行比較,但是在操作時位元組流和字元流的操作完成之後都不關閉輸出流。

範例:使用位元組流不關閉執行

Java代碼  

java 位元組流與字元流的差別
  1. package org.lxh.demo12.byteiodemo;    
  2. import java.io.File;    
  3. import java.io.FileOutputStream;    
  4. import java.io.OutputStream;    
  5. public class OutputStreamDemo05 {    
  6. public static void main(String[] args) throws Exception {   // 異常抛出,  不處理    
  7. // 第1步:使用File類找到一個檔案    
  8.      File f = new File("d:" + File.separator + "test.txt"); // 聲明File  對象    
  9. // 第2步:通過子類執行個體化父類對象    
  10.      OutputStream out = null;            
  11. // 準備好一個輸出的對象    
  12.      out = new FileOutputStream(f);      
  13. // 通過對象多态性進行執行個體化    
  14. // 第3步:進行寫操作    
  15.      String str = "Hello World!!!";      
  16. // 準備一個字元串    
  17.      byte b[] = str.getBytes();          
  18. // 字元串轉byte數組    
  19.      out.write(b);                      
  20. // 将内容輸出    
  21.  // 第4步:關閉輸出流    
  22.     // out.close();                  
  23. // 此時沒有關閉    
  24.         }    
  25.     }   

程式運作結果:

java 位元組流與字元流的差別

此時沒有關閉位元組流操作,但是檔案中也依然存在了輸出的内容,證明位元組流是直接操作檔案本身的。而下面繼續使用字元流完成,再觀察效果。

範例:使用字元流不關閉執行

Java代碼  

java 位元組流與字元流的差別
  1. package org.lxh.demo12.chariodemo;    
  2. import java.io.File;    
  3. import java.io.FileWriter;    
  4. import java.io.Writer;    
  5. public class WriterDemo03 {    
  6.     public static void main(String[] args) throws Exception { // 異常抛出,  不處理    
  7.         // 第1步:使用File類找到一個檔案    
  8.         File f = new File("d:" + File.separator + "test.txt");// 聲明File 對象    
  9.         // 第2步:通過子類執行個體化父類對象    
  10.         Writer out = null;                 
  11. // 準備好一個輸出的對象    
  12.         out = new FileWriter(f);            
  13. // 通過對象多态性進行執行個體化    
  14.         // 第3步:進行寫操作    
  15.         String str = "Hello World!!!";      
  16. // 準備一個字元串    
  17.         out.write(str);                    
  18. // 将内容輸出    
  19.         // 第4步:關閉輸出流    
  20.         // out.close();                   
  21. // 此時沒有關閉    
  22.     }    
  23. }   

程式運作結果:

java 位元組流與字元流的差別

程式運作後會發現檔案中沒有任何内容,這是因為字元流操作時使用了緩沖區,而   在關閉字元流時會強制性地将緩沖區中的内容進行輸出,但是如果程式沒有關閉,則緩沖區中的内容是無法輸出的,是以得出結論:字元流使用了緩沖區,而位元組流沒有使用緩沖區。

提問:什麼叫緩沖區?

在很多地方都碰到緩沖區這個名詞,那麼到底什麼是緩沖區?又有什麼作用呢?

回答:緩沖區可以簡單地了解為一段記憶體區域。

可以簡單地把緩沖區了解為一段特殊的記憶體。

某些情況下,如果一個程式頻繁地操作一個資源(如檔案或資料庫),則性能會很低,此時為了提升性能,就可以将一部分資料暫時讀入到記憶體的一塊區域之中,以後直接從此區域中讀取資料即可,因為讀取記憶體速度會比較快,這樣可以提升程式的性能。

在字元流的操作中,所有的字元都是在記憶體中形成的,在輸出前會将所有的内容暫時儲存在記憶體之中,是以使用了緩沖區暫存資料。

如果想在不關閉時也可以将字元流的内容全部輸出,則可以使用Writer類中的flush()方法完成。

範例:強制性清空緩沖區

Java代碼  

java 位元組流與字元流的差別
  1. package org.lxh.demo12.chariodemo;    
  2. import java.io.File;    
  3. import java.io.FileWriter;    
  4. import java.io.Writer;    
  5. public class WriterDemo04 {    
  6.     public static void main(String[] args) throws Exception { // 異常抛出不處理    
  7.         // 第1步:使用File類找到一個檔案    
  8.         File f = new File("d:" + File.separator + "test.txt");// 聲明File    
  9. 對象    
  10.         // 第2步:通過子類執行個體化父類對象    
  11.         Writer out = null;                   
  12. // 準備好一個輸出的對象    
  13.         out = new FileWriter(f);             
  14. // 通過對象多态性進行執行個體化    
  15.         // 第3步:進行寫操作    
  16.         String str = "Hello World!!!";      
  17. // 準備一個字元串    
  18.         out.write(str);                    
  19. // 将内容輸出    
  20.         out.flush();                       
  21. // 強制性清空緩沖區中的内容    
  22.         // 第4步:關閉輸出流    
  23.         // out.close();                
  24. // 此時沒有關閉    
  25.     }    
  26. }   

程式運作結果:

java 位元組流與字元流的差別

此時,檔案中已經存在了内容,更進一步證明内容是儲存在緩沖區的。這一點在讀者日後的開發中要特别引起注意。

提問:使用位元組流好還是字元流好?

學習完位元組流和字元流的基本操作後,已經大概地明白了操作流程的各個差別,那麼在開發中是使用位元組流好還是字元流好呢?

回答:使用位元組流更好。

在回答之前,先為讀者講解這樣的一個概念,所有的檔案在硬碟或在傳輸時都是以位元組的方式進行的,包括圖檔等都是按位元組的方式存儲的,而字元是隻有在記憶體中才會形成,是以在開發中,位元組流使用較為廣泛。

位元組流與字元流主要的差別是他們的的處理方式

流分類:

1.Java的位元組流

   InputStream是所有位元組輸入流的祖先,而OutputStream是所有位元組輸出流的祖先。

2.Java的字元流

  Reader是所有讀取字元串輸入流的祖先,而writer是所有輸出字元串的祖先。

InputStream,OutputStream,Reader,writer都是抽象類。是以不能直接new 

位元組流是最基本的,所有的InputStream和OutputStream的子類都是,主要用在處理二進制資料,它是按位元組來處理的

但實際中很多的資料是文本,又提出了字元流的概念,它是按虛拟機的encode來處理,也就是要進行字元集的轉化

這兩個之間通過 InputStreamReader,OutputStreamWriter來關聯,實際上是通過byte[]和String來關聯

在實際開發中出現的漢字問題實際上都是在字元流和位元組流之間轉化不統一而造成的

在從位元組流轉化為字元流時,實際上就是byte[]轉化為String時,

public String(byte bytes[], String charsetName)

有一個關鍵的參數字元集編碼,通常我們都省略了,那系統就用作業系統的lang

而在字元流轉化為位元組流時,實際上是String轉化為byte[]時,

byte[]    String.getBytes(String charsetName)

也是一樣的道理

至于java.io中還出現了許多其他的流,按主要是為了提高性能和使用友善,

如BufferedInputStream,PipedInputStream等