2012-06-06 36 views
5

Tôi hiện đang có các mã sau đó đọc một tập tin nằm trên web và ghi nó vào một tập tin trên điện thoại:Có thể xác định kích thước tệp cần tải xuống?

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); 

Có ai biết cho dù đó là có thể (bằng cách sử dụng cài đặt trên hay cách khác) để xác định tổng số byte sẽ được đọc trước khi bắt đầu tải xuống (để xuất bản tiến độ phần trăm cho người dùng dưới dạng số tiền tải xuống)?

Trả lời

6

sử dụng phương pháp getContentLength của 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

Ngoài ra độ dài nội dung có thể là -1 nếu máy chủ không hỗ trợ điều này hoặc vì lý do nào đó, kích thước tệp không xác định. –

+0

CẢNH BÁO: 'url.openConnection(). GetContentLength()' sẽ thực hiện 'GET' chứ không phải' HEAD'. Xem câu trả lời từ Santosh bên dưới để biết phương thức tốt hơn (tức là, thực hiện 'connection.setRequestMethod (" HEAD ")' trước khi gọi 'getContentLength()'). –

2

Bạn có thể gửi yêu cầu tới máy chủ để trả lại kích thước. Sử dụng tập tin đó trong thanh tiến trình của bạn và bắt đầu tải xuống. Vì vậy, đây là hai yêu cầu riêng biệt nhưng bạn có thể nhóm chúng trong cùng một nhiệm vụ asyc. Vì vậy, trước tiên bạn có được fielszie, thực hiện cuộc gọi đến progressUpdate nơi bạn đặt các giá trị cho thanh tiến trình và sau đó tiếp tục tải xuống với các cuộc gọi định kỳ tới progressUpdate() để thay đổi trạng thái của thanh tiến trình.

3

thử điều này bằng cách sử dụng 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

Phương pháp getContentLength của URLConnection nên cung cấp cho bạn biết kích thước của tập tin được tải về. Từ đó, bạn có thể vẽ ProgressBar của mình theo ý muốn, cập nhật nó (trong onProgressUpdate, giả sử bạn đang làm điều này bên trong AsyncTask. Bạn đúng không?) Bất cứ khi nào dữ liệu mới được xử lý bởi fileOutputStream của bạn.

Nếu máy chủ không cung cấp cho bạn giá trị trong getContentLength (-1 trong hầu hết các trường hợp, nhưng ít nhất hãy kiểm tra xem nó có nhỏ hơn hoặc bằng không), chỉ cần làm cho ProgressBar của bạn không xác định.

3

để xác định tổng số byte mà là để được đọc trước bắt đầu với việc tải xuống, một cách là chỉ nhận các tiêu đề phản ứng bằng cách gửi một HTTP yêu cầu HEAD như sau:

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; 
     } 
    } 
} 

Điều này sẽ in kích thước của nội dung được tải xuống mà không thực sự tải xuống nội dung.

+0

Tài liệu của phương thức 'URLConnection.getContentLength()' (được gợi ý bởi những người trả lời khác) đọc: "Trả về độ dài nội dung theo byte được chỉ định bởi trường tiêu đề phản hồi' nội dung độ dài' hoặc -1 nếu trường này không được đặt . " Vì vậy, có vẻ như phương pháp này trên thực tế cũng không tải xuống nội dung. Đúng nếu tôi đã sai lầm. –

+1

Adil, Vâng, đúng vậy. Nó chỉ nhận tiêu đề mà không kích hoạt tải xuống tệp. – Santosh

+0

Không, 'url.openConnection(). GetContentLength()' sẽ thực hiện một 'GET' (trong ít nhất là Java 7). Thiết lập phía máy chủ và kiểm tra các yêu cầu mà máy khách Java gửi qua. –

Các vấn đề liên quan