InputStream類只能讀取一次


最近在學安卓,寫着寫着無意間發現這樣一個問題,InputStream 對象讀過一次之后便為空,一直想不到原因,代碼如下:

 1 public Bitmap getBitMap(String path) throws Exception{
 2         URL url=new URL(path);
 3         HttpURLConnection conn=(HttpURLConnection) url.openConnection();
 4         conn.setConnectTimeout(5000);
 5         conn.setRequestMethod("GET");
 6         if(conn.getResponseCode()==200){
 7             InputStream is=conn.getInputStream();   // 在這獲取輸入流
 8             String name=path.substring(path.lastIndexOf("/")+1);
 9             File file=new File(Environment.getExternalStorageDirectory(),name);
10             FileOutputStream fos=new FileOutputStream(file);
11             byte [] buffer=new byte[1024];
12             int len=0;
13             while((len=is.read(buffer))!=-1){                    //在這使用過is對象
14                 fos.write(buffer,0,len);
15             }
16             return BitmapFactory.decodeStream(is);       //返回的bitmap對象為空,很奇怪吧?
17         }
18         return null;
19     }
20     

然后去重新看了下java基礎知識,發現inputstream類不能讀取兩次,有人這樣比喻,InputStream就類比成一個杯子,杯子里的水就像InputStream里的數據,你把杯子里的水拿出來了,杯子的水就沒有了,InputStream也是同樣的道理!!所以你想要多次使用InputStream里面的數據,那就保存在一個String里面,這樣你想怎么用就怎么用,也沒有必要去重復去讀InputStream。

 

深入了解發現InputStream不能讀取兩次是因為,在InputStream讀取的時候,會有一個pos指針,他指示每次讀取之后下一次要讀取的起始位置,比如說下面的例子

 1 @Test
 2     public void testByteArrayInputStream() throws Exception {
 3         String str = "AAAAACCCCcCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
 4         //ByteArrayInputStream是把一個byte數組轉換成一個字節流,讀取的內容是從byte數組中讀取的
 5         ByteArrayInputStream byteInputStream = new ByteArrayInputStream(str.getBytes());
 6         
 7         //調用這個方法,會影響到下次讀取,下次再調用這個方法,讀取的起始點會后移5個byte,
 8         byteInputStream.read(new byte[5]);
 9         
10         //ByteArrayOutputStream生成對象的時候,是生成一個100大小的byte的緩沖區,寫入的時候,是把內容寫入內存中的一個緩沖區
11         ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(100);
12         
13         int i =0;
14         byte [] b = new byte[100];
15         while((i = byteInputStream.read(b))!= -1){
16             byteOutput.write(b, 0, i);
17         }
18         System.out.println(new String(byteOutput.toByteArray()));
19     }

打印結果是:CCCCcCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

如果要打印出完整的str,去掉第8行  或者 在第九行添加代碼,如下

@Test
    public void testByteArrayInputStream() throws Exception {
        String str = "AAAAACCCCcCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
        //ByteArrayInputStream是把一個byte數組轉換成一個字節流,讀取的內容是從byte數組中讀取的
        ByteArrayInputStream byteInputStream = new ByteArrayInputStream(str.getBytes());
        
        //調用這個方法,會影響到下次讀取,下次再調用這個方法,讀取的起始點會后移5個byte
        byteInputStream.read(new byte[5]);
        byteInputStream.reset();//調用reset方法可以使read中的pos指針復位
        
        
        //ByteArrayOutputStream生成對象的時候,是生成一個100大小的byte的緩沖區,寫入的時候,是把內容寫入內存中的一個緩沖區
        ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(100);
        
        int i =0;
        byte [] b = new byte[100];
        while((i = byteInputStream.read(b))!= -1){
            byteOutput.write(b, 0, i);
        }
        System.out.println(new String(byteOutput.toByteArray()));
    }

打印結果是:AAAAACCCCcCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

 

 

所以可以知道一般我們使用inputStream,需要在一次內處理完所有邏輯。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM