1. 程式人生 > >Java InputStream讀取資料問題

Java InputStream讀取資料問題

Java InputStream讀取資料問題

======================================================================

原理講解 


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()方法才能將資料總數全部得到。

      如果這樣寫程式碼:

[java] view plain copy print?
  1. int count = in.available();    
  2.   byte[] b = newbyte[count];    
  3.   in.read(b);  
int count = in.available();  
  byte[] b = new byte[count];  
  in.read(b);
在進行網路操作時往往出錯,因為你呼叫available()方法時,對發發送的資料可能還沒有到達,你得到的count是0。
         需要改成這樣:
[java] view plain
copy print?
  1. int count = 0;    
  2.  while (count == 0) {    
  3.   //count = in.available();  
  4.   count=response.getEntity().getContentLength();//(HttpResponse response)  
  5.  }    
  6.  byte[] b = newbyte[count];    
  7.  in.read(b);   
int count = 0;  
 while (count == 0) {  
  //count = in.available();  
  
  count=response.getEntity().getContentLength();//(HttpResponse response)  
 }  
 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個位元組,最好用以下程式碼: [java] view plain copy print?
  1. <span style="color:#CC0000;">byte[] bytes = newbyte[count];    
  2. int readCount = 0// 已經成功讀取的位元組的個數  
  3. while (readCount < count) {    
  4.  readCount += in.read(bytes, readCount, count - readCount);    
  5. }</span>    
  <span style="color:#CC0000;">byte[] bytes = new byte[count];  
  int readCount = 0; // 已經成功讀取的位元組的個數  
  while (readCount < count) {  
   readCount += in.read(bytes, readCount, count - readCount);  
  }</span>  

用這段程式碼可以保證讀取count個位元組,除非中途遇到IO異常或者到了資料流的結尾(EOFException).

==========================================================================================

程式碼分享

下面分享我自己寫的測試程式碼片段,供大家參考:

[java] view plain copy print?
  1. /**  
  2.      * <b>獲取指定的URL返回的資料資訊</b>  
  3.      * @param <font color="#efac10"><a href="http://www.baidu.com">_url:指定的URL</a></font>  
  4.      * @return  
  5.      * @throws ClientProtocolException  
  6.      * @throws IOException  
  7.      */
  8.     public String getReponse(String _url) throws ClientProtocolException, IOException    
  9.     {    
  10.         String readContent=null;    
  11.         DefaultHttpClient httpclient = new DefaultHttpClient();    
  12.         HttpGet httpget = new HttpGet(SinaJsonTest.SinaUrl);    
  13.         System.out.println("0.Send the URL to Sina Sever....");    
  14.         HttpResponse response = httpclient.execute(httpget);    
  15.         HttpEntity entity = response.getEntity();    
  16.         System.out.println("1.Get Response Status: " + response.getStatusLine());    
  17.         if (entity != null) {    
  18.             System.out.println("  Get ResponseContentEncoding():"+entity.getContentEncoding());    
  19.             System.out.println("  Content Length():"+entity.getContentLength());    
  20.             //getResponse  
  21.             InputStream in=entity.getContent();    
  22.             int count = 0;    
  23.             while (count == 0) {    
  24.              count = Integer.parseInt(""+entity.getContentLength());//in.available();  
  25.             }    
  26.             byte[] bytes = newbyte[count];    
  27.             int readCount = 0// 已經成功讀取的位元組的個數  
  28.             while (readCount <= count) {    
  29.              if(readCount == count)break;    
  30.              readCount += in.read(bytes, readCount, count - readCount);    
  31.             }    
  32.             //轉換成字串  
  33.             readContent= new String(bytes, 0, readCount, "UTF-8"); // convert to string using bytes  
  34.             System.out.println("2.Get Response Content():\n"+readContent);    
  35.         }    
  36.         return readContent;    
  37.     }    

相關推薦

Java InputStream讀取資料問題

Java InputStream讀取資料問題 ====================================================================== 原理講解  1. 關於InputStream.read()      在從資料流裡讀取

Java InputStream讀取網路響應Response資料的方法

Java InputStream讀取資料問題 ====================================================================== 原理講解  1. 關於InputStream.read()   &n

Java InputStream讀取網路響應Response資料的方法!(重要)

Java InputStream讀取資料問題 ====================================================================== 原理講解  1. 關於InputStream.read()      在從資料流裡讀取

JAVA InputStream讀取檔案資料

1. 關於InputStream.read()      在從資料流裡讀取資料時,為圖簡單,經常用InputStream.read()方法。這個方法是從流裡每次只讀取讀取一個位元組,效率會非常低。     更好的方法是用InputStream.read(byte[] b)或

java InputStream讀取數據問題

數據流 ble 本地 www 取數 麻煩 length byte[] 發送 原文 1. 關於InputStream.read() 在從數據流裏讀取數據時,為圖簡單,經常用InputStream.read()方法。這個方法是從流裏每次只讀取讀取一個字節,效率會非常低

Java實現讀取Excel指定列的指定行的資料

package utils; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import j

Java API 讀取HBase表資料

Java API 讀取HBase表資料 1. 在使用java api 去獲取資料的時候,先用 hbase shell 展示一下 hbase 中的表。 hbase(main):005:0> scan 'tsdb-uid' ROW

Java讀取資料夾大小的6種方法及程式碼

這篇文章介紹了JAVA讀取資料夾大小的幾種方法例項,有需要的朋友可以參考一下。 (一)單執行緒遞迴方式 package com.taobao.test; import java.io.File; public class TotalFileSizeSequential { pub

java解析Excel,使用InputStream讀取檔案

一、需要匯入的jar包 <dependency>             <groupId>org.apache.poi</groupId>             <artifactId>poi</ar

Java中將InputStream讀取為String, 各種方法的效能對比

如下, 一共存在11種實現方式及其對應的效能測試結果: 1. 使用IOUtils.toString (Apache Utils) String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);

Java呼叫R ,從資料庫讀取資料,用R根據讀取資料生成圖片儲存

Java呼叫R 以及用R生成的圖片儲存 使用 png()可以保證圖片質量 有人說繪製的圖片上有中文會出現亂碼,其實設定下字型就好了 family=‘STXihei’ Java呼叫R 以及用R生成的圖片儲存 Rserve的配置和啟動: ①安裝Rserve包。

Java解析(讀取)Json資料

以前看過書上說,XML是web service間傳輸資訊的標準格式吧,就看了看XML。最近在做個網站,又說是有了JSON,第一回聽說就看了看,總結總結一下。 1.JSON介紹   JSON比XML簡單,主要體現在傳輸相同資訊的情況下,檔案的大小不同。   JSON只用於傳輸資訊,

Java實現在文字檔案中寫入資料讀取資料

Java實現在文字檔案中寫入資料和讀取資料 寫資料到文字檔案中去: 程式碼如下所示: import java.io.File; import java.io.FileWriter; import java.io.IOException; public class

java poi讀取excel表格資料

package com.tl.web.signup.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.i

java快速讀取文字檔案最後一行資料內容,文字檔案非常大

http://www.iteye.com/problems/42748 public static void main(String[] args) throws Exception { File file = new File("E:/a.txt"); // 100M

Java 讀取資料夾檢查是否新增檔案 檔案監聽器

建立一個檔案監聽器 監聽資料夾下檔案的變化  使用 commons-io 中的檔案監控  import java.util.concurrent.TimeUnit; import org.apache.commons.io.filefilter.FileFilterU

Java從CSV檔案中讀取資料和寫入

.CSV檔案是以逗號分割的資料倉儲,讀取資料時從每一行中讀取一條資料元祖,也就是一條資料,再用字元分割的方式獲取表中的每一個數據項。 package com.conn.csv;

java中hashtable怎樣儲存資料讀取資料

Hashtable-雜湊表類 以雜湊表的形式儲存資料,資料的形式是鍵值對. 特點: 查詢速度快,遍歷相對慢 鍵值不能有空指標和重複資料 建立Hashtable<Integer,String> ht=new Hashtable<Integer,String>(); 添值 ht.put(

java工具類之Excel檔案匯入、讀取資料(支援xls、和xlsx)

所需的jar包:poi的jar包儘量保持一致,不然會報版本不一致的錯誤下面是程式碼:package ReadExcel; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.

JAVA讀取資料夾裡的檔案目錄到TXT

package javapackge; import java.awt.*; import java.awt.event.*; import java.io.File; import javax.swing.JFrame; class MyWindowDemo{ private Frame f