Adil Hussain
Adil Hussain

Reputation: 32221

Possible to determine size of file to be downloaded?

I currently have the following code which reads a file located on the web and writes it to a file on the phone:

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

Does anyone know whether it is possible (using the setup above or otherwise) to determine the total number of bytes which are to be read before commencing with the download (in order to publish percentage progress to the user as the download proceeds)?

Upvotes: 6

Views: 8980

Answers (5)

try this out using URLConnnection

URLConnection connection = new URL(sourceFileWebAddress).openConnection();
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);

Upvotes: 3

Santosh
Santosh

Reputation: 17923

TO determine the total number of bytes which are to be read before commencing with the download, one way is to only get the response headers by sending a HTTP HEAD request as follows:

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

This will print the size of the content to be downloaded without actually downloading the contents.

Upvotes: 3

josephus
josephus

Reputation: 8304

The method getContentLength of URLConnection should give you the size of the file to be downloaded. From this you can draw your ProgressBar as you like, updating it (in onProgressUpdate, assuming you're doing this inside an AsyncTask. you are, right?) whenever new data is processed by your fileOutputStream.

If the server doesn't give you a value in getContentLength (-1 in most cases, but at least check if it's less than or equal to zero), just make your ProgressBar indeterminate.

Upvotes: 1

Ed.
Ed.

Reputation: 1952

use the getContentLength method of 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);

Upvotes: 9

Orlymee
Orlymee

Reputation: 2357

You can send a request to the server to return the filesize. Use that filesize in your progressbar and initiate the download.So these are two separate requests but you can bundle them in the same asyc task. So you first get the fielszie, make a call to progressUpdate where you set the values for progressbar and then continue with the download with periodic calls to progressUpdate() to change the status of progressbar.

Upvotes: 2

Related Questions