2

I have read many articles in this site, but could not find a working solution. I am downloading file from a url. If the download is interrupted i would like to resume from where it was interrupted.

Source code:

URL url = new URL("url");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Range",file.length()+"-");
connection.connect();

input = connection.getInputStream();
output = new FileOutputStream("/sdcard/Android/appdata/tmp/tmpdl/something.apk");

byte data[] = new byte[4096];
long total = 0;
int count;
continueDownload = true;

while ((count = input.read(data)) != -1 && continueDownload)
{
     total += count;
     output.write(data, 0, count);
     System.out.println("continueDownload1: " + continueDownload);
}

any idea! thanks

Mateusz Sroka
  • 2,255
  • 2
  • 17
  • 19
Shoaib
  • 167
  • 2
  • 14
  • 1
    Check out this answer: http://stackoverflow.com/questions/3428102/how-to-resume-an-interrupted-download-part-2 – Amit Bhati Jan 25 '16 at 12:28

1 Answers1

1

Here is one more thing to say… The server must support ranges (search more info about the HTTP header “Accept-Ranges: bytes”) … This is not an obvious thing and not every and each server does it (my experience is that many servers don’t support it) …

Then you can modify your solution for example using this: http://blog.adeel.io/2017/09/24/resuming-a-http-download-in-java/

But how it works, actually? The server sends the whole file for the first time. After something breaks the connection, then a new connection must be made and the server must receive request to send only a portion of the downloaded file – it accepts missing range of bytes, then it resumes the download sending only the data that were requested for the second time; even then something may break the connection (again) and even then the whole process must be repeated again. This means that you must also “resume” your download on your (client) side – you have to start again and send the “Range” header from the client side.

According to the source above you must check if your file is partially downloaded:

// Add this right after you initialize httpUrlConnection but before beginning download
if (file.exists())
    httpUrlConnection.setRequestProperty("Range", "bytes=" + file.length() + "-");

and also open the file appending the data:

// And then you’d initialize the file output stream like so:
if (file.exists())
    fos = new FileOutputStream(file, true); // resume download, append to existing file
else
    fos = new FileOutputStream(file);

(I recommend to store the file.exists result to some Boolean variable…)

But be aware of that you never know in advance how much bytes you have to receive until your loop finishes correctly… Good praxis is to save your data in some temporary file (e.g. *.*-part) and after the download runs to the end completely rename it to the correct name… (Browsers do that, too.)

(… I hope it helps to someone even after a time…)

Roman Horváth
  • 148
  • 1
  • 8