2012-06-06 29 views
5

目前,我有下面的代碼讀取位於網絡上的文件,並將其寫入一個文件在手機上:可以確定要下載的文件的大小?

InputStream inputStream = new URL(sourceFileWebAddress).openStream(); 
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); 
FileOutputStream fileOutputStream = new FileOutputStream(targetFile); 

int count; 
byte buffer[] = new byte[1024]; 

while ((count = bufferedInputStream.read(buffer, 0, buffer.length)) != -1) 
    fileOutputStream.write(buffer, 0, count); 

有誰知道是否有可能(使用上述設置或以其他方式),以確定在開始下載之前要讀取的字節總數(爲了在下載過程中向用戶發佈百分比進度)?

回答

6

使用URLConnection

URL url = new URL(sourceFileWebAddress); 
URLConnection connection = url.openConnection(); 
connection.connect(); 

int fileLenth = connection.getContentLength(); 

InputStream inputStream = url.openStream(); 
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); 
+4

此外,如果服務器不支持該內容或由於某種原因文件大小未知,內容長度可能爲-1。 –

+0

警告:'url.openConnection()。getContentLength()'將執行GET,而不是'HEAD'。請參閱下面Santosh的回答以獲得更好的方法(即,在調用getContentLength()之前執行'connection.setRequestMethod(「HEAD」)')。 –

2

您可以向服務器發送請求以返回文件大小。在進度條中使用該文件大小並啓動​​下載。因此,這些是兩個單獨的請求,但您可以將它們捆綁在相同的asyc任務中。 因此,您首先得到fielszie,撥打電話progressUpdate,在其中設置進度條的值,然後通過定期調用progressUpdate()來繼續下載,以更改進度條的狀態。

3

getContentLength方法嘗試了這一點使用URLConnnection

URLConnection connection = new URL(sourceFileWebAddress).openStream(); 
InputStream stream = connection.getInputStream(); 

System.out.println("total size: "+connection.getContentLength();//size 

BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); 
FileOutputStream fileOutputStream = new FileOutputStream(targetFile); 

int count; 
byte buffer[] = new byte[1024]; 

while ((count = bufferedInputStream.read(buffer, 0, buffer.length)) != -1) 
    fileOutputStream.write(buffer, 0, count); 
1

URLConnectiongetContentLength的方法應該給你的文件的大小來進行下載。從這裏你可以隨心所欲地繪製你的ProgressBar,只要你的fileOutputStream處理新的數據,就更新它(在onProgressUpdate中,假設你在AsyncTask中做這件事,對嗎?)。

如果服務器在getContentLength中不給你一個值(在大多數情況下爲-1,但至少檢查它是否小於或等於零),只需讓你的ProgressBar不確定。

3

,以確定哪些與下載開始之前被讀取的總字節數,一個方法是將僅通過發送HTTP HEAD請求如下得到響應頭

import java.io.IOException; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.ProtocolException; 
import java.net.URL; 

public class SimpleHTTPRequest { 

    public static void main(String[] args) { 
     HttpURLConnection connection = null; 
     URL serverAddress = null; 

     try { 
      String sourceFileWebAddress = "http://localhost:8080/mycontents"; 
      serverAddress = new URL(sourceFileWebAddress); 
      //set up out communications stuff 
      connection = null; 

      //Set up the initial connection 
      connection = (HttpURLConnection)serverAddress.openConnection(); 

      //HEAD request will make sure that the contents are not downloaded. 
      connection.setRequestMethod("HEAD"); 

      connection.connect(); 
      System.out.println("========"+connection.getContentLength()); 

     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (ProtocolException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     finally 
     { 
      //close the connection, set all objects to null 
      connection.disconnect(); 

      connection = null; 
     } 
    } 
} 

這將打印下載內容的大小而實際上沒有下載的內容。

+0

「URLConnection.getContentLength()」方法的文檔(由其他answerers建議)的內容如下:「返回由響應頭字段'content-length'指定的字節的內容長度,如果未設置此字段,則返回-1 「。所以看來這種方法實際上並沒有下載內容。糾正我,如果我錯了。 –

+1

Adil,是的,是的。它只接收標題而不觸發文件下載。 – Santosh

+0

不,'url.openConnection()。getContentLength()'會做一個GET(至少在Java 7中)。設置服務器端並檢出Java客戶端發送的請求。 –