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

InputStreamavailable 方法总是返回 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()方法获取文件的总大小的更多相关文章

  1. fileInputStream.available()获取 文件的总大小

    available():返回与之关联的文件的字节数 我们用inputStream.available()获取 文件的总大小

  2. 获取文件夹总大小方法2_获取cmd命令结果,效率最高

    public static long GetDirectorySize(string path) { long res = 0; System.Diagnostics.Process p = new ...

  3. (判断url文件大小)关于inputStream.available()方法获取下载文件的总大小

    转自:http://hold-on.iteye.com/blog/1017449 如果用inputStream对象的available()方法获取流中可读取的数据大小,通常我们调用这个函数是在下载文件 ...

  4. 使用Class.getResource和ClassLoader.getResource方法获取文件路径

    自从转投Java阵营后,一直发下Java程序的路径读取异常麻烦,因此查阅了比较多的版本内容,整合了一份自己的学习笔记.主要使用Class及通过ClassLoader来动态获取文件路径. 查阅链接如下: ...

  5. 【转载】使用Class.getResource和ClassLoader.getResource方法获取文件路径

    自从转投Java阵营后,一直发下Java程序的路径读取异常麻烦,因此查阅了比较多的版本内容,整合了一份自己的学习笔记.主要使用Class及通过ClassLoader来动态获取文件路径. 查阅链接如下: ...

  6. linux查找某段时间修改的文件的总大小

    1.统计 2017-10-25 16:30:00 至 2017-10-25 19:30:00 修改的文件的总大小 b= for i in `find -type f \( -newermt '2017 ...

  7. ffmpeg获取文件的总时长(mp3/mp4/flv等)

    使用ffmpeg.exe获取文件属性信息,C#中可以在进程外异步调用这个工具,如下: using (System.Diagnostics.Process pro = new System.Diagno ...

  8. Python - 批量获取文件夹的大小输出为文件格式化保存

    很多时候,查看一个文件夹下的每个文件大小可以轻易的做到,因为文件后面就是文件尺寸,但是如果需要查看一个文件夹下面所有的文件夹对应的尺寸,就发现需要把鼠标放到对应的文件夹上,稍等片刻才会出结果. 有时候 ...

  9. python获取文件夹的大小(即取出所有文件计算大小)

    import os path = r'/Users/authurchen/PycharmProjects/Demo' # print(os.listdir(path)) ls = os.listdir ...

随机推荐

  1. oracle删除表以及清理表空间

    若要彻底删除表,则使用语句:drop table <table_name> purge; 清除回收站里的信息 清除指定表:purge table <table_name>; 清 ...

  2. Linux中source是什么指令?

    命令用法: source FileName 作用:在当前bash环境下读取并执行FileName中的命令. 注:该命令通常用命令“.”来替代. 如:source /etc/profile 与 .  / ...

  3. jQuery的$.ajax示例

    $.ajax({ url: 'index.php?module=products&submod=product_experience_manage&method=ajaxGetSele ...

  4. Swift---TextView用法

    1.TextView放在一个NSScrollView中,作为documentView存在. @IBOutlet weak var txtScrollView: NSScrollView! 2.在Tex ...

  5. android Activity基类通用方法

    public class BaseActivity extends Activity { Resources res; // 通用资源缩写 @Override protected void onCre ...

  6. 数据源和JNDI的关系:

    DataSource对象是由Tomcat提供的,因此不能在程序中采用创建一个实例的方式来生产DataSource对象,而需要采用Java的另一个技术JNDI,来获得DataSource对象的引用. T ...

  7. 关于js css html加载顺序整理

    1.js放在head中会立即执行,阻塞后续的资源下载与执行.因为js有可能会修改dom,如果不阻塞后续的资源下载,dom的操作顺序不可控. 正常的网页加载流程是这样的. 浏览器一边下载HTML网页,一 ...

  8. Unity手游之路<十一>资源打包Assetbundle

    http://blog.csdn.net/janeky/article/details/17652021 在手游的运营过程中,更新资源是比不可少的.资源管理第一步是资源打包.传统的打包可以将所有物件制 ...

  9. [POJ1068]Parencodings

    [POJ1068]Parencodings 试题描述 Let S = s1 s2...s2n be a well-formed string of parentheses. S can be enco ...

  10. 剑指Offer 树的子结构

    题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构)     思路: 分为2个部分.1先找出A中和B根节点相同的节点r. 2,咱判断B中所有孩子节点是不 ...