InputStream中read()與read(byte[] b)

read()與read(byte[] b)這兩個方法在抽象類InputStream中前者是作爲抽象方法存在的,後者不是,JDK API中是這樣描述兩者的: 

1:read() : 
從輸入流中讀取數據的下一個字節,返回0到255範圍內的int字節值。如果因爲已經到達流末尾而沒有可用的字節,則返回-1。在輸入數據可用、檢測到流末尾或者拋出異常前,此方法一直阻塞。 

2:read(byte[] b) :  
從輸入流中讀取一定數量的字節,並將其存儲在緩衝區數組 b 中。以整數形式返回實際讀取的字節數。在輸入數據可用、檢測到文件末尾或者拋出異常前,此方法一直阻塞。如果 b 的長度爲 0,則不讀取任何字節並返回 0;否則,嘗試讀取至少一個字節。如果因爲流位於文件末尾而沒有可用的字節,則返回值 -1;否則,至少讀取一個字節並將其存儲在 b 中。將讀取的第一個字節存儲在元素 b[0] 中,下一個存儲在 b[1] 中,依次類推。讀取的字節數最多等於 b 的長度。設 k 爲實際讀取的字節數;這些字節將存儲在 b[0] 到 b[k-1] 的元素中,不影響 b[k] 到 b[b.length-1] 的元素。 

由幫助文檔中的解釋可知,read()方法每次只能讀取一個字節,所以也只能讀取由ASCII碼範圍內的一些字符。這些字符主要用於顯示現代英語和其他西歐語言。而對於漢字等unicode中的字符則不能正常讀取。只能以亂碼的形式顯示。 

對於read()方法的上述缺點,在read(byte[] b)中則得到了解決,就拿漢字來舉例,一個漢字佔有兩個字節,則可以把參數數組b定義爲大小爲2的數組即可正常讀取漢字了。當然b也可以定義爲更大,比如如果b=new byte[4]的話,則每次可以讀取兩個漢字字符了,但是需要注意的是,如果此處定義b 的大小爲3或7等奇數,則對於全是漢字的一篇文檔則不能全部正常讀寫了。 

下面用實例來演示一下二者的用法: 
實例說明:類InputStreamTest1.Java 來演示read()方法的使用。類InputStreamTest2.java來演示read(byte[] b)的使用。兩個類的主要任務都是通過文件輸入流FileInputStream來讀取文本文檔xuzhimo.txt中的內容,並且輸出到控制檯上顯示。 

先看一下xuzhimo.txt文檔的內容 



InputStreamTest1.java 

Java代碼 複製代碼 收藏代碼
  1. /**  
  2.  * User: liuwentao  
  3.  * Time: 12-1-25 上午10:11  
  4.  */  
  5. public class InputStreamTest1 {   
  6.     public static void main(String[] args){   
  7.         String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\classes\\demo\\java\\inputstream\\";   
  8.         File file = new File(path + "xuzhimo.txt");   
  9.         InputStream inputStream = null;   
  10.         int i=0;   
  11.         try {   
  12.             inputStream = new FileInputStream(file);   
  13.             while ((i = inputStream.read())!=-1){   
  14.                 System.out.print((char)i + "");   
  15.             }   
  16.         }catch (FileNotFoundException e) {   
  17.             e.printStackTrace();   
  18.         } catch (IOException e) {   
  19.             e.printStackTrace();   
  20.         }   
  21.     }   
  22. }  
[java] view plaincopy
  1. /** 
  2.  * User: liuwentao 
  3.  * Time: 12-1-25 上午10:11 
  4.  */  
  5. public class InputStreamTest1 {  
  6.     public static void main(String[] args){  
  7.         String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\classes\\demo\\java\\inputstream\\";  
  8.         File file = new File(path + "xuzhimo.txt");  
  9.         InputStream inputStream = null;  
  10.         int i=0;  
  11.         try {  
  12.             inputStream = new FileInputStream(file);  
  13.             while ((i = inputStream.read())!=-1){  
  14.                 System.out.print((char)i + "");  
  15.             }  
  16.         }catch (FileNotFoundException e) {  
  17.             e.printStackTrace();  
  18.         } catch (IOException e) {  
  19.             e.printStackTrace();  
  20.         }  
  21.     }  
  22. }  

執行結果: 



如果將while循環中的 (char)去掉,即改成: 
引用
System.out.print(i + "");

則執行結果: 



InputStreamTest2.java 
Java代碼 複製代碼 收藏代碼
  1. /**  
  2.  * User: liuwentao  
  3.  * Time: 12-1-25 上午10:11  
  4.  */  
  5. public class InputStreamTest2 {   
  6.     public static void main(String[] args){   
  7.         String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\src\\demo\\java\\inputstream\\";   
  8.         File file = new File(path + "xuzhimo.txt");   
  9.         InputStream inputStream = null;   
  10.         int i=0;   
  11.         try {   
  12.             inputStream = new FileInputStream(file);   
  13.             byte[] bytes = new byte[16];   
  14.             while ((i = inputStream.read(bytes))!=-1){   
  15.                 String str = new String(bytes);   
  16.                 System.out.print(str);   
  17.             }   
  18.         }catch (FileNotFoundException e) {   
  19.             e.printStackTrace();   
  20.         } catch (IOException e) {   
  21.             e.printStackTrace();   
  22.         }   
  23.     }   
  24. }  
[java] view plaincopy
  1. /** 
  2.  * User: liuwentao 
  3.  * Time: 12-1-25 上午10:11 
  4.  */  
  5. public class InputStreamTest2 {  
  6.     public static void main(String[] args){  
  7.         String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\src\\demo\\java\\inputstream\\";  
  8.         File file = new File(path + "xuzhimo.txt");  
  9.         InputStream inputStream = null;  
  10.         int i=0;  
  11.         try {  
  12.             inputStream = new FileInputStream(file);  
  13.             byte[] bytes = new byte[16];  
  14.             while ((i = inputStream.read(bytes))!=-1){  
  15.                 String str = new String(bytes);  
  16.                 System.out.print(str);  
  17.             }  
  18.         }catch (FileNotFoundException e) {  
  19.             e.printStackTrace();  
  20.         } catch (IOException e) {  
  21.             e.printStackTrace();  
  22.         }  
  23.     }  
  24. }  

執行結果: 

 

遺憾的是,還是有亂碼,解決辦法可以參見下面教程 
http://wentao365.iteye.com/blog/1183951 

修改後的代碼: 
Java代碼 複製代碼 收藏代碼
  1. /**  
  2.  * User: liuwentao  
  3.  * Time: 12-1-25 上午10:11  
  4.  */  
  5. public class InputStreamTest3 {   
  6.     public static void main(String[] args) {   
  7.         String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\src\\demo\\java\\inputstream\\";   
  8.         File file = new File(path + "xuzhimo.txt");   
  9.         InputStream inputStream = null;   
  10.         String line;   
  11.         StringBuffer stringBuffer = new StringBuffer();   
  12.         try {   
  13.             //InputStream :1)抽象類,2)面向字節形式的I/O操作(8 位字節流) 。   
  14.             inputStream = new FileInputStream(file);   
  15.             //Reader :1)抽象類,2)面向字符的 I/O操作(16 位的Unicode字符) 。   
  16.             Reader reader = new InputStreamReader(inputStream, "UTF-8");   
  17.             //增加緩衝功能   
  18.             BufferedReader bufferedReader = new BufferedReader(reader);   
  19.             while ((line = bufferedReader.readLine()) != null) {   
  20.                 stringBuffer.append(line);   
  21.             }   
  22.             if (bufferedReader != null) {   
  23.                 bufferedReader.close();   
  24.             }   
  25.             String content = stringBuffer.toString();   
  26.             System.out.print(content);   
  27.         } catch (FileNotFoundException e) {   
  28.             e.printStackTrace();   
  29.         } catch (IOException e) {   
  30.             e.printStackTrace();   
  31.         }   
  32.     }   
  33. }  
[java] view plaincopy
  1. /** 
  2.  * User: liuwentao 
  3.  * Time: 12-1-25 上午10:11 
  4.  */  
  5. public class InputStreamTest3 {  
  6.     public static void main(String[] args) {  
  7.         String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\src\\demo\\java\\inputstream\\";  
  8.         File file = new File(path + "xuzhimo.txt");  
  9.         InputStream inputStream = null;  
  10.         String line;  
  11.         StringBuffer stringBuffer = new StringBuffer();  
  12.         try {  
  13.             //InputStream :1)抽象類,2)面向字節形式的I/O操作(8 位字節流) 。  
  14.             inputStream = new FileInputStream(file);  
  15.             //Reader :1)抽象類,2)面向字符的 I/O操作(16 位的Unicode字符) 。  
  16.             Reader reader = new InputStreamReader(inputStream, "UTF-8");  
  17.             //增加緩衝功能  
  18.             BufferedReader bufferedReader = new BufferedReader(reader);  
  19.             while ((line = bufferedReader.readLine()) != null) {  
  20.                 stringBuffer.append(line);  
  21.             }  
  22.             if (bufferedReader != null) {  
  23.                 bufferedReader.close();  
  24.             }  
  25.             String content = stringBuffer.toString();  
  26.             System.out.print(content);  
  27.         } catch (FileNotFoundException e) {  
  28.             e.printStackTrace();  
  29.         } catch (IOException e) {  
  30.             e.printStackTrace();  
  31.         }  
  32.     }  
  33. }  

執行結果: 



還是遺憾,沒有換行。 

解決辦法,通過 commons-io-*.jar 
Java代碼 複製代碼 收藏代碼
  1. /**  
  2.  * User: liuwentao  
  3.  * Time: 12-1-25 上午10:11  
  4.  */  
  5. public class InputStreamTest4 {   
  6.     public static void main(String[] args) {   
  7.         String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\src\\demo\\java\\inputstream\\";   
  8.         File file = new File(path + "xuzhimo.txt");   
  9.   
  10.         String content = null;   
  11.         try {   
  12.             content = FileUtils.readFileToString(file, "utf-8");   
  13.         } catch (IOException e) {   
  14.             e.printStackTrace();   
  15.         }   
  16.         System.out.println("content:" + content);   
  17.     }   
  18. }  
[java] view plaincopy
  1. /** 
  2.  * User: liuwentao 
  3.  * Time: 12-1-25 上午10:11 
  4.  */  
  5. public class InputStreamTest4 {  
  6.     public static void main(String[] args) {  
  7.         String path = "D:\\project\\opensouce\\opensouce_demo\\base_java\\src\\demo\\java\\inputstream\\";  
  8.         File file = new File(path + "xuzhimo.txt");  
  9.   
  10.         String content = null;  
  11.         try {  
  12.             content = FileUtils.readFileToString(file, "utf-8");  
  13.         } catch (IOException e) {  
  14.             e.printStackTrace();  
  15.         }  
  16.         System.out.println("content:" + content);  
  17.     }  
  18. }  

執行結果: 

 


 

java InputStream讀取數據問題


http://blog.csdn.net/happyq/article/details/7992885

1. 關於InputStream.read()
     在從數據流裏讀取數據時,爲圖簡單,經常用InputStream.read()方法。這個方法是從流裏每次只讀取讀取一個字節,效率會非常低。     更好的方法是用InputStream.read(byte[] b)或者InputStream.read(byte[] b,int off,int len)方法,一次讀取多個字節。


2. 關於InputStream類的available()方法
    要一次讀取多個字節時,經常用到InputStream.available()方法,這個方法可以在讀寫操作前先得知數據流裏有多少個字節可以讀取。需要注意的是,如果這個方法用在從本
地文件讀取數據時,一般不會遇到問題,但如果是用於網絡操作,就經常會遇到一些麻煩。比如,Socket通訊時,對方明明發來了1000個字節,但是自己的程序調用available()方法卻只得到900,或者100,甚至是0,感覺有點莫名其妙,怎麼也找不到原因。其實,這是因爲網絡通訊往往是間斷性的,一串字節往往分幾批進行發送。本地程序調用available()方法有時得到0,這可能是對方還沒有響應,也可能是對方已經響應了,但是數據還沒有送達本地。對方發送了1000個字節給你,也許分成3批到達,這你就要調用3次available()方法才能將數據總數全部得到。
      如果這樣寫代碼:
  int count = in.available();
  byte[] b = new byte[count];
  in.read(b);
      在進行網絡操作時往往出錯,因爲你調用available()方法時,對發發送的數據可能還沒有到達,你得到的count是0。
         需要改成這樣:
  int count = 0;
  while (count == 0) {
   count = in.available();
  }
  byte[] b = new byte[count];
  in.read(b);
3. 關於InputStream.read(byte[] b)和InputStream.read(byte[] b,int off,int len)這兩個方法都是用來從流裏讀取多個字節的,有經驗的程序員就會發現,這兩個方法經常 讀取不到自己想要讀取的個數的字節。比如第一個方法,程序員往往希望程序能讀取到b.length個字節,而實際情況是,系統往往讀取不了這麼多。仔細閱讀Java的API說明就發現了,這個方法 並不保證能讀取這麼多個字節,它只能保證最多讀取這麼多個字節(最少1個)。因此,如果要讓程序讀取count個字節,最好用以下代碼:
  byte[] b = new byte[count];
  int readCount = 0; // 已經成功讀取的字節的個數
  while (readCount < count) {
   readCount += in.read(bytes, readCount, count - readCount);
  }
      用這段代碼可以保證讀取count個字節,除非中途遇到IO異常或者到了數據流的結尾(EOFException)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章