使用InputStream的available()能否用来判断当前流是否读取到文件
作者:蓝奕世
InputStream available()能否用来判断当前流是否读取到文件
读取minio中的文件的时候,通过以下代码。
InputStream inputStream = minioClient.getObject(minio_bucketNameExam,fileurl);
而我想做的事情是在读取完了以后判断一下
inputStream.available()
是否等于0,如果等于0的话,就判断没有从minio中读取到数据,如果大于0的话就判断已经读取到minio中的数据。
那么这样做对不对呢?
知道解决问题后我才知道不能这样去判断,当然也不是绝对的,如果你是循环一行一行的去读,也可以使用这个方法,首先来说一下available()这个方法的作用:
该方法的描述是这样的:
返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取的字节数.返回一个整数值,来获取还有多少字节可以读取。
如上,由于是从网络中获取数据,由于存在着网络延迟等因素,所以可能获取的长度是错误的。也就是每次得到的数字可能不一样
当然,如果是读取本地文件的话,这个方法返回的数据大小一般是真实的。因此,如何使用以及要不要用这个方法,得根据具体的场景
为什么有的时候已经读取到数据,返回值还是0呢?
这个方法在进行网络操作时往往出错,因为你调用available()方法时,对发发送的数据可能还没有到达,你得到的count是0。
也有可能一次就读取完了,根本没有下一次,那下一次获取的数据肯定也是0。
FileInputStream与InputStream的available()方法的作用
available()方法
如果要从网络中下载文件时,我们知道网络是不稳定的,也就是说网络下载时,read()方法是阻塞的,说明这时我们用inputStream.available()获取不到文件的总大小。
此时就需要通过
HttpURLConnection httpconn = (HttpURLConnection)url.openConnection(); httpconn.getContentLength();//获取文件长度
来获取文件的大小。
对于一般的接口调用,可以使用inputStream.available()方法获取返回值的数据的长度大小 如下:
//建立http连接 http.connect(); //获取输入流 InputStream is = http.getInputStream(); //获取信息的长度 int size = is.available(); //创建字节数组用来存储流数据 byte[] b = new byte[size]; //将流数据读入字节数组中 is.read(b);
但是在 FileInputStream中已经重写了这个方法,重写之后的方法是通过文件的描述来获取文件的大小的。
那么,我们来看看哪些地方可以用available()方法来获取文件大小,进而用来定义缓冲数组的长度。
1.在本地文件文件中,这里我一般是直接使用的。
2.网络中的文件
- a.比如web 中http 里面的文件流里面,第一种情况有content-length,那么小文件的情况,我们是直接可以通过request 获取该属性,也就知道文件的大小了。
- b.在某些情况下,比如文件比较大,采用采用分段方式,长连接的方式发送,不能一次知道文件大小,http 的header 里面就没有上面的content-length 属性,而是变成了Transfer-Encoding: chunked属性,这表示分段发送信息,但是对整个文件的接受,可以通过一些标志位,或者一些超时限制等方法处理,这里不具体研究了。
- c.socket 传输文件,是没重写available方法的,也就是说我们不能通过这个知道流的字节数,一般情况下,我们可以先发送一段自定义的header 过去,描述文件大小,然后再循环持续获取流信息。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。