天天看點

[Android Pro] 關于inputStream.available()方法擷取檔案的總大小

 如果用inputStream對象的available()方法擷取流中可讀取的資料大小,通常我們調用這個函數是在下載下傳檔案或者對檔案進行其他處理時擷取檔案的總大小。

 以前在我們初學File和inputStream和outputStream時,有需要将檔案從一個檔案夾複制到另一個檔案夾中,這時候我們用的就是inputStream.available()來擷取檔案的總大小,而且屢試不爽。

但是當我們要從網絡URL中下載下傳一個檔案時,我們發現得到的數值并不是需要下載下傳的檔案的總大小。

好吧。我們看看JDK文檔中怎麼解釋。

傳回此輸入流下一個方法調用可以不受阻塞地從此輸入流讀取(或跳過)的估計位元組數。下一個調用可能是同一個線程,也可能是另一個線程。一次讀取或跳過此估計數個位元組不會受阻塞,但讀取或跳過的位元組數可能小于該數。

注意,有些 <code>InputStream</code> 的實作将傳回流中的位元組總數,但也有很多實作不會這樣做。試圖使用此方法的傳回值配置設定緩沖區,以儲存此流所有資料的做法是不正确的。

類 <code>InputStream</code> 的 <code>available</code> 方法總是傳回 <code>0</code>。

此方法應該由子類重寫。

inputStream 源代碼

[Android Pro] 關于inputStream.available()方法擷取檔案的總大小
[Android Pro] 關于inputStream.available()方法擷取檔案的總大小

 這裡傳回的是 0 值。

是以說要從網絡中下載下傳檔案時,我們知道網絡是不穩定的,也就是說網絡下載下傳時,read()方法是阻塞的,說明這時我們用

inputStream.available()擷取不到檔案的總大小。

但是從本地拷貝檔案時,我們用的是FileInputStream.available(),難道它是将先将硬碟中的資料先全部讀入流中?

然後才根據此方法得到檔案的總大小?

好吧,我們來看看FileInputStream源代碼吧

[Android Pro] 關于inputStream.available()方法擷取檔案的總大小
[Android Pro] 關于inputStream.available()方法擷取檔案的總大小

這裡重寫了inputStream中的available()方法

關鍵是:fileSystem.ioctlAvailable(fd.descriptor);

調用了FileSystem這是java沒有公開的一個類,JavaDoc API沒有。

其中

fileSystem 是一個IFileSystem對象,IFileSySTEM是java沒有公開的一個類,JavaDoc API中沒有;

fd是一個FileDescriptor對象,即檔案描述符

說明這句代碼應該是通過檔案描述符擷取檔案的總大小,而并不是事先将磁盤上的檔案資料全部讀入流中,再擷取檔案總大小

搞清楚了這些,但是我們的主要問題沒有解決,怎麼獲得網絡檔案的總大小?

我想原理應該都差不多,應該也是通過一個類似檔案描述符的東西來擷取。

 網絡下載下傳擷取檔案總大小的代碼:

 我們再來看看httpconn.getContentLength();

[Android Pro] 關于inputStream.available()方法擷取檔案的總大小
[Android Pro] 關于inputStream.available()方法擷取檔案的總大小

關鍵:getHeaderFieldInt("Content-Length", -1);

意思是從http預解析頭中擷取“Content-length”字段的值

其實也是類似從檔案描述符中擷取檔案的總大小

本文轉自demoblog部落格園部落格,原文連結http://www.cnblogs.com/0616--ataozhijia/p/4973102.html如需轉載請自行聯系原作者

demoblog

繼續閱讀