[Android Pro] 关于inputStream.available()方法获取文件的总大小
reference to :http://hold-on.iteye.com/blog/1017449
如果用inputStream对象的available()方法获取流中可读取的数据大小,通常我们调用这个函数是在下载文件或者对文件进行其他处理时获取文件的总大小。
以前在我们初学File和inputStream和outputStream时,有需要将文件从一个文件夹复制到另一个文件夹中,这时候我们用的就是inputStream.available()来获取文件的总大小,而且屡试不爽。
但是当我们要从网络URL中下载一个文件时,我们发现得到的数值并不是需要下载的文件的总大小。
好吧。我们看看JDK文档中怎么解释。
available
public int available()
throws IOException
注意,有些 InputStream 的实现将返回流中的字节总数,但也有很多实现不会这样做。试图使用此方法的返回值分配缓冲区,以保存此流所有数据的做法是不正确的。
如果已经调用 close() 方法关闭了此输入流,那么此方法的子类实现可以选择抛出 IOException。
类 InputStream 的 available 方法总是返回 0。
此方法应该由子类重写。
返回: 可以不受阻塞地从此输入流读取(或跳过)的估计字节数;如果到达输入流末尾,则返回 0。 抛出: IOException - 如果发生 I/O 错误。
inputStream 源代码
/**
* Returns the number of bytes that are available before this stream will
* block. This implementation always returns 0. Subclasses should override
* and indicate the correct number of bytes available.
*
* @return the number of bytes available before blocking.
* @throws IOException
* if an error occurs in this stream.
* @since Android 1.0
*/
public int available() throws IOException {
return 0;
}
这里返回的是 0 值。
所以说要从网络中下载文件时,我们知道网络是不稳定的,也就是说网络下载时,read()方法是阻塞的,说明这时我们用
inputStream.available()获取不到文件的总大小。
但是从本地拷贝文件时,我们用的是FileInputStream.available(),难道它是将先将硬盘中的数据先全部读入流中?
然后才根据此方法得到文件的总大小?
好吧,我们来看看FileInputStream源代码吧
/**
* Returns the number of bytes that are available before this stream will
* block. This method always returns the size of the file minus the current
* position.
*
* @return the number of bytes available before blocking.
* @throws IOException
* if an error occurs in this stream.
* @since Android 1.0
*/
@Override
public int available() throws IOException {
openCheck(); // BEGIN android-added // Android always uses the ioctl() method of determining bytes
// available. See the long discussion in
// org_apache_harmony_luni_platform_OSFileSystem.cpp about its
// use. return fileSystem.ioctlAvailable(fd.descriptor);
// END android-added // BEGIN android-deleted
// synchronized (repositioningLock) {
// // stdin requires special handling
// if (fd == FileDescriptor.in) {
// return (int) fileSystem.ttyAvailable();
// }
//
// long currentPosition = fileSystem.seek(fd.descriptor, 0L,
// IFileSystem.SEEK_CUR);
// long endOfFilePosition = fileSystem.seek(fd.descriptor, 0L,
// IFileSystem.SEEK_END);
// fileSystem.seek(fd.descriptor, currentPosition,
// IFileSystem.SEEK_SET);
// return (int) (endOfFilePosition - currentPosition);
// }
// END android-deleted
}
这里重写了inputStream中的available()方法
关键是:fileSystem.ioctlAvailable(fd.descriptor);
调用了FileSystem这是java没有公开的一个类,JavaDoc API没有。
其中
fileSystem 是一个IFileSystem对象,IFileSySTEM是java没有公开的一个类,JavaDoc API中没有;
fd是一个FileDescriptor对象,即文件描述符
说明这句代码应该是通过文件描述符获取文件的总大小,而并不是事先将磁盘上的文件数据全部读入流中,再获取文件总大小
搞清楚了这些,但是我们的主要问题没有解决,怎么获得网络文件的总大小?
我想原理应该都差不多,应该也是通过一个类似文件描述符的东西来获取。
网络下载获取文件总大小的代码:
HttpURLConnection httpconn = (HttpURLConnection)url.openConnection();
httpconn.getContentLength();
我们再来看看httpconn.getContentLength();
/**
* Gets the content length in bytes specified by the response header field
* {@code content-length} or {@code -1} if this field is not set.
*
* @return the value of the response header field {@code content-length}.
* @since Android 1.0
*/
public int getContentLength() {
return getHeaderFieldInt("Content-Length", -1);
}
关键:getHeaderFieldInt("Content-Length", -1);
意思是从http预解析头中获取“Content-length”字段的值
其实也是类似从文件描述符中获取文件的总大小
[Android Pro] 关于inputStream.available()方法获取文件的总大小的更多相关文章
- fileInputStream.available()获取 文件的总大小
available():返回与之关联的文件的字节数 我们用inputStream.available()获取 文件的总大小
- 获取文件夹总大小方法2_获取cmd命令结果,效率最高
public static long GetDirectorySize(string path) { long res = 0; System.Diagnostics.Process p = new ...
- (判断url文件大小)关于inputStream.available()方法获取下载文件的总大小
转自:http://hold-on.iteye.com/blog/1017449 如果用inputStream对象的available()方法获取流中可读取的数据大小,通常我们调用这个函数是在下载文件 ...
- 使用Class.getResource和ClassLoader.getResource方法获取文件路径
自从转投Java阵营后,一直发下Java程序的路径读取异常麻烦,因此查阅了比较多的版本内容,整合了一份自己的学习笔记.主要使用Class及通过ClassLoader来动态获取文件路径. 查阅链接如下: ...
- 【转载】使用Class.getResource和ClassLoader.getResource方法获取文件路径
自从转投Java阵营后,一直发下Java程序的路径读取异常麻烦,因此查阅了比较多的版本内容,整合了一份自己的学习笔记.主要使用Class及通过ClassLoader来动态获取文件路径. 查阅链接如下: ...
- linux查找某段时间修改的文件的总大小
1.统计 2017-10-25 16:30:00 至 2017-10-25 19:30:00 修改的文件的总大小 b= for i in `find -type f \( -newermt '2017 ...
- ffmpeg获取文件的总时长(mp3/mp4/flv等)
使用ffmpeg.exe获取文件属性信息,C#中可以在进程外异步调用这个工具,如下: using (System.Diagnostics.Process pro = new System.Diagno ...
- Python - 批量获取文件夹的大小输出为文件格式化保存
很多时候,查看一个文件夹下的每个文件大小可以轻易的做到,因为文件后面就是文件尺寸,但是如果需要查看一个文件夹下面所有的文件夹对应的尺寸,就发现需要把鼠标放到对应的文件夹上,稍等片刻才会出结果. 有时候 ...
- python获取文件夹的大小(即取出所有文件计算大小)
import os path = r'/Users/authurchen/PycharmProjects/Demo' # print(os.listdir(path)) ls = os.listdir ...
随机推荐
- MySQL源码分析以及目录结构 2
原文地址:MySQL源码分析以及目录结构作者:jacky民工 主要模块及数据流经过多年的发展,mysql的主要模块已经稳定,基本不会有大的修改.本文将对MySQL的整体架构及重要目录进行讲述. 源码结 ...
- 自己动手开发jQuery插件
因为工作需要,所以这几天琢磨了一下关于jQuery插件开发的问题,经过一天鏖战,终于完成自己动手做的第一个jQuery插件,对于俺这种见了css就蛋疼菊紧的人来说,一天时间8小时,保守估计有5个小时在 ...
- HDU 5592
原题: http://acm.hdu.edu.cn/showproblem.php?pid=5592 线段树的变形,先说思路. 题目中给出了当前节点之前的逆序对数,则p[i]-p[i-1]就是对于p[ ...
- DOM的相关优化
为什么要进行DOM优化? DOM对象本身也是一个js对象,所以严格来说,并不是操作这个对象慢,而是说操作了这个对象后,会触发一些浏览器行为,比如布局(layout)和绘制(paint). 首先先说一些 ...
- centos 修改DNS,网关,IP地址
1.CentOS 修改DNS 修改对应网卡的DNS的配置文件 # vi /etc/resolv.conf 修改以下内容 nameserver 8.8.8.8 #google域名服务器 nameser ...
- python 字节与字符串转换
name = 'laogaoyang' nameBytes = name.encode('utf-8') # 字节 nameStr = nameBytes.decode('utf-8')# 字符串 p ...
- (原创)在service中定时执行网络操作的几点说明
执行网络操作是耗时操作,即便是在service中也要放到子线程中执行 这里我用到了async-http-client框架来执行异步请求操作 计时用的java原生Timer和TimerTask类 本来这 ...
- Qt5 任务栏托盘功能实现
23333 有一阵子没写博客了,研究了挺长时间qt,学到任务栏托盘时简直无语,网上找得到的代码大多是废码,Qt5不支持或者本身就有毛病不能实现却被n多人转来转去的,甚是无语. 简单托盘功能以下在Qt5 ...
- BZOJ 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦
Description 给你每个点与相邻点的距离和方向,求两点间的曼哈顿距离. \(n \leqslant 4\times 10^4\) . Sol 加权并查集. 像向量合成一样合并就可以了,找 \( ...
- 简单的哈希表实现 C语言
简单的哈希表实现 简单的哈希表实现 原理 哈希表和节点数据结构的定义 初始化和释放哈希表 哈希散列算法 辅助函数strDup 哈希表的插入和修改 哈希表中查找 哈希表元素的移除 哈希表打印 测试一下 ...