输入流重复读取问题,解决InputStream引发的空指针问题

来源:互联网 发布:手机淘宝安全中心在哪 编辑:程序博客网 时间:2024/05/16 04:43

  1.    写安卓demo小程序,通过HttpClient获取了json文件,首先通过HttpResponse转换json为List,然后用同一个HttpResponse获取的输入流将json数据写入SdCard,然后程序一直异常,学安卓并不久,调试不太精通,废了很大功夫,发现了这个问题。
  1.   

  2.   总结:同一个输入流只能读取一次,虽然以前使用socket编程时知道这个问题但是不小心还是会忘记。每次从输入流读取了数据之后,输入流中的这些数据就无法读取了,就好比真正的水管一样,水流出来就真的不在水管中了。在文件流读取完之后数据引用会定位到输入流数据末端,无法再用该输入流读取读取过的数据。若用read()方法则返回-1,若要重新读取,则要用到mark和reset方法。这两个方法只适用于BufferedInputStream,InputStream 的 mark 方法不执行任何操作。  ,因为缓冲流会在本地内存缓存数据,它就可以延长缓存数据的生存时间,达到二次读取的效果。


  1. public void mark(int readlimit)  
  1.         在此输入流中标记当前的位置。对 reset 方法的后续调用会在最后标记的位置重新定位此流,以便后续读取前面读取过的的字节。   
  1.         readlimit 参数为从mark标记开始允许读取的字节数。   
  1.         mark 的常规协定是:如果方法 markSupported 返回 true,那么输入流总是在调用 mark 之后记录所有读取的字节,并时刻准备在调用方法 reset 时,再次提供这些相同的字节。如果在mark之后读取的数据的大小大于readlimit和BufferedInputStream类的缓冲区大小两者中的最大值则mark标记无效。 
  1.   
  2. 如果要重复读取的数据量比较小,可以尝试使用BufferedInputStream的mark/reset方法。
    如果重复读取的数据量比较大,不适用同一个缓冲区的重复使用,那么,重复创建相应的输入流对象。
  1. 注意:mark和reset方法只能在BufferedInputStream中使用,BufferedInputStream类调用mark(int readlimit)方法后读取多少字节标记才失效,是取readlimit和BufferedInputStream类的缓冲区大小两者中的最大值,而并非完全由readlimit确定。
  2.   
0 0