最近在使用input.read(byty[] buffer)的时候,经常发现读取的字节数小于buffer.length,而流本身的长度是超过buffer.length的,多次测试,发现第一次读取的时候经常会遇到此问题

 
  1. int i=-1;  
  2. while((i=in.read(buffer))>0){  
  3. //..文件写入操作  
  4. }  

 

        我之前觉得类似上面的代码是没有问题的,直到最近跟踪代码的时候才发现,第一次read的字节数经常是介于0和bufer.length之前的数,仔细查看了jdk的api,发现问题所在:

        in.read(buffer)并不能保证读取的字节数一定是buffer.length,虽然我们是这么希望的,这只能限定读取的最大字节数不会超过buffer.length,但之前我们使用的时候并没有发现,是因为使用时有两种情况:

        1、读取本地inputStream是不会出现问题的

        2、读取网络获取的inputStream会有可能出现这样的问题

        究其原因,根据api的说法执行read操作的时候会先锁定inputStream,直到调用available()得到inputStream长度的时 候才会继续read操作,而当通过网络获取inputStream时,数据不是一次获取到,available()方法返回的有可能并不是全部数据的长 度,而是已获取的数据长度,举个例子:如果数据总长度是1024字节,通过网络获取inputStream,当执行available()时,可能只获取 了100个字节,而如果byte[] 定义了200个字节长度,就会出现读不满的情况!

        所以,如果希望读取长度为count个字节数据应该用类似一下代码确保读取完整:

 
  1. byte[] b = new byte[count];  
  2. int readCount = 0// 已经读取字节数  
  3. while (readCount < count) {  
  4.     readCount += in.read(bytes, readCount, count - readCount);  
  5.  }  

        问题解决之后,反思自己,都是没看api惹的祸,另外java的api最好还是看jdk的api,之前看android的api,解释说明都省略了