天天看點

inputstream.available()與HttpURLConnection.getContentLength()

先看看下面這段代碼(有删節)

public static String send(String sendurl, String sendText) throws Exception {

   URL url = null;

   URLConnection uc = null;

//建立連接配接、輸出資料等;

String strReceive = ""; 

   try {

    InputStream is = uc.getInputStream();

    DataInputStream in = new DataInputStream(is);

   int blockLen = in.available();

    byte block[] = new byte[blockLen];

   for (int readLen = -9999; readLen != -1;) {

      readLen = in.read(block);

      if (readLen != -1)

       strReceive = strReceive + new String(block);

     }

    is.close();

    in.close();

   } catch (IOException e) {

    logger.info("httpl接收錯誤1:" + e.getMessage());

   }

   return strReceive;

}

注意紅色字型那幾行。blockLen被用來建立一個位元組數組block,block作為資料緩沖來讀取inputstream裡的資料。然後循環 從inputstream中讀取資料,寫入block中。

考慮一種情況。如果網絡阻塞了,inputstream已經打開,但是資料卻還沒有傳輸過來,會發生什麼?

inputstream.available()方法傳回的值是該inputstream在不被阻塞的情況下一次可以讀取到的資料長度。如果資料還 沒有傳輸過來,那麼這個inputstream勢必會被阻塞,進而導緻inputstream.available傳回0。而對 inputstream.read(byte[] b)而言,如果b的長度等于0,該方法将傳回0。

回頭看看這個循環體的結束條件,是readLen == -1時跳出。顯然,上面提到的網絡阻塞情況發生之後,代碼将陷入這個死循環當中。

這是我們在工程應用中遇到的一個問題。由外包商提供的工具jar包中的這段代碼,直接将我們的伺服器 拉進了死循環。

我們的解決方法,是将整個接收與發送的方法進行改寫,使用了下面的這段代碼:

   HttpClient client = new HttpClient();

    PostMethod method = new PostMethod(prpUrl);

    method.setRequestBody(sendstr);

    method.getParams().setParameter(

      HttpMethodParams.HTTP_CONTENT_CHARSET, "GBK");

    client.executeMethod(method);

    // rtnXml = method.getResponseBodyAsString();

    InputStream txtis = method.getResponseBodyAsStream();

    BufferedReader br = new BufferedReader(new InputStreamReader(txtis));

    String tempbf;

    StringBuffer html = new StringBuffer(100);

    while ((tempbf = br.readLine()) != null) {

     html.append(tempbf);

    }

    rtnXml = html.toString();

    method.releaseConnection();

确确實實的,解決了問題。

如果仍然要采用原方法中手動打開輸入流、建立緩沖區、循環讀取資料的方法,那麼不應該用 available這個字段來作為緩沖區的初始長度。可以考慮手工設定一個固定值;或者讀取http封包頭的content-length屬性值。最後的 這種方式沒有嘗試過。

本文轉自 斯然在天邊 51CTO部落格,原文連結:http://blog.51cto.com/winters1224/799056,如需轉載請自行聯系原作者