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,需要在一次内处理完所有逻辑。

 

 

posted @ 2013-10-31 23:19  会做菜的老狼  阅读(4899)  评论(0编辑  收藏  举报