踩過的坑系列之InputStream.read(byte[])方法

轉自:https://www.cnblogs.com/lylife/p/5519109.htmlhtml

 

項目以前都是好好的,最近現場那邊出現一個問題,報錯不是合法的json字符串,這個json字符串是經過http請求訪問得到的。json

  經過直接在瀏覽器上直接訪問http這個請求,發現返回的json也是徹底正確的。後來排查代碼才發現了原來錯誤出在從字節流中讀取數據這裏:數組

  看下以前出錯代碼:這個方法是處理InputStream,而後返回成一個字符串。瀏覽器

複製代碼
 1 public String process(InputStream in, String charset) {
 2      byte[] buf = new byte[1024];
 3      StringBuffer sb = new StringBuffer();
 4      try {
 5          while (in.read(buf) != -1) {
 6              sb.append(new String(buf, charset));
 7          }
 8     } catch (IOException e) {
 9          e.printStackTrace();
10     }
11      return sb.toString();
12 }
複製代碼

   有問題的代碼在第6行,發現以前項目沒出錯的緣由是InputStream裏面的數據少,還不夠1024個字節,while那裏循環一次就行了,獲得一個正確格式的json串;後面出錯了是由於InputStream裏面數據比較多,while須要2次了,第一次讀取以後buf裏面滿了,第二次讀取發現read(byte[])方法不會去清空緩衝區數組,第二次實際上read字節只有100個,buf裏面只替換前100個字節內容,而後經過第6行代碼append到字符串裏了,就形成了最後得到的字符串不是json格式,形成以後json解析出錯。app

  知道問題後,將以前代碼改成下,既然每次不會去清空緩衝區數組內容,那就經過讀取長度來append字符串,問題解決:字體

複製代碼
 1 public String process(InputStream in, String charset) {
 2     byte[] buf = new byte[1024];
 3     StringBuffer sb = new StringBuffer();
 4     int len = 0;
 5     try {
 6         while ((len=in.read(buf)) != -1) {
 7             sb.append(new String(buf, 0, len, charset));
 8         }
 9     } catch (IOException e) {
10         e.printStackTrace();
11     }
12     return sb.toString();
13 }
複製代碼

 

    後來查了下JDK API,發現API上也說明過了,只是之前沒注意,關鍵在於加黑字體,不影響b[k]到b[b.length-1]的元素:spa

  附上API:code

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