[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 ...
随机推荐
- 牡丹江.2014B(图论,树的直径)
B - Building Fire Stations Time Limit:5000MS Memory Limit:131072KB 64bit IO Format:%lld & ...
- Hibernate面试题
一.谈一谈Hibernate的缓存机制 1.一级缓存: 内部缓存存在于HIbernate中又叫一级缓存,他属于应用事务级缓存. 2.二级缓存: 01.应用级缓存. 02.分布式缓存. 条件:数据不会被 ...
- 【python网络编程】新浪爬虫:关键词搜索爬取微博数据
上学期参加了一个大数据比赛,需要抓取大量数据,于是我从新浪微博下手,本来准备使用新浪的API的,无奈新浪并没有开放关键字搜索的API,所以只能用爬虫来获取了.幸运的是,新浪提供了一个高级搜索功能,为我 ...
- java中的方法重载与重写以及方法修饰符
1. 方法重载Overloading , 是在一个类中,有多个方法,这些方法的名字相同,但是具有不同的参数列表,和返回值 重载的时候,方法名要一样,但是参数类型和参数个数不一样,返回值类型可以相同,也 ...
- 在同一个页面使用多个不同的jQuery版本,让它们并存而不冲突
- jQuery自诞生以来,版本越来越多,而且jQuery官网的新版本还在不断的更新和发布中,现已经达到了1.6.4版本,但是我们在以前的项目中就已经使用了旧版本的jQuery,比如已经出现的:1.3 ...
- C++多线程的几个重要方法解析CreateEvent / SetEvent /ResetEvent/ 等
1.CreateEvent 是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面. 函功能描述:创建或打开一个命名的或无名的事件对象. HANDLE m_hExit; m_hExit= ...
- 淘宝(阿里百川)手机客户端开发日记第十一篇 JSP+Servlet
由于本人从事.net开发已有多年经验,今天由于工作需要,我只能学习下JSP+Servlet,至于java web提供了更好的开发框架MVC,现在由于时间关系,我只好用JSP+Servlet来搭建服务器 ...
- 全栈工程师学习Linux技术的忠告
随着科技的普及,Linux作为最受欢迎的服务端操作系统,无人不知,无人不晓.当今,不论是服务器搭建,还是客户端开发,Linux系统的基础技能对全栈来说都是必备的,而了解如下几个问题可以更好的帮助你成为 ...
- X.Org可能将失去它的域名x.org
X.Org基金会面临失去它的一个重要资产:单字母域名x.org.过去半年里,围绕着x.org域名的所有权问题,X.Org基金会董事会尝试私下解 决,但未能如愿.域名将于1月19日过期,只剩下不到两周的 ...
- windows7 + cocos2d-x 3.2 +vs2012 速度真的很慢
每次编译要大半天,简直伤不起,这样效率如何上的去???有谁有办法?