最近在學安卓,寫着寫着無意間發現這樣一個問題,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,需要在一次內處理完所有邏輯。