zoukankan      html  css  js  c++  java
  • 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,需要在一次内处理完所有逻辑。

  • 相关阅读:
    实现自己的Linq to Sql
    [分享] 浅谈项目需求变更管理
    【分享】老程序员的经验和价值在哪里?
    程序员是自己心中的“上帝”
    [分享]解析“程序员的十大技术烦恼”
    【分享】帮助你早些明白一些道理
    “风雨20年”的20条精辟编程经验
    【分享】 优秀程序员的代码是“活的”
    给开发人员培训时的语录
    【分享】SQL Server优化50法
  • 原文地址:https://www.cnblogs.com/fzll/p/3400558.html
Copyright © 2011-2022 走看看