how to resume an interrupted download - part 2
To resume a download, you need to send not only the Range
request header, but also the If-Range
request header which should contain either the unique file identifier or the file modification timestamp.
If the server returns an ETag
response header on the initial download, then you should use it in the If-Range
header of the subsequent resume requests. Or if it returns a Last-Modified
response header, then you should use it in the If-Range
request header instead.
Looking at your logs, the server has sent a Last-Modified
response header. So you should send it back along in an If-Range
header of the resume request.
// Initial download.
String lastModified = connection.getHeaderField("Last-Modified");
// ...
// Resume download.
connection.setRequestProperty("If-Range", lastModified);
The server will use this information to verify if you're requesting exactly the same file.
how to resume an interrupted download
Try using a "Range" request header:
// Open connection to URL.
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Specify what portion of file to download.
connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
// here "downloaded" is the data length already previously downloaded.
// Connect to server.
connection.connect();
Having done that, you can seek
at a given point (just before the length of your download data, say X
) and start writing the newly downloaded data there. Be sure to use the same value X
for the range header.
Details about 14.35.2 Range Retrieval Requests
More details and source code can be found here
How to resume interrupted download of specific part of file automatically in curl?
It's clear that server doesn't support byte ranges
Continue an interrupted download on iPhone
ASIHTTPRequest has easy to use support for resuming downloads:
http://allseeing-i.com/ASIHTTPRequest/How-to-use#resume
Alternatively, find out how much data you have downloaded already by looking at the size of the existing data, and set the 'Range' header on your NSMutableURLRequest:
[request addValue:@"bytes=x-" forHTTPHeaderField:@"Range"];
..where x is the size in bytes of the data you have already. This will download data starting from byte x. You can then append this data to your file as you receive it.
Note that the web server you are downloading from must support partial downloads for the resource you are trying to download - it sends the Accept-Ranges header if so. You can't generally resume downloads for dynamically generated content (e.g. a page generated by a script on the server).
How to reconnect in requests to continue a download
There is no inbuilt function to do that so you will have to Manually do that .
First thing you need to do is keep record of how many chunks/buffers you have written to file.
Before download function declare some variable, say x=0. (To count how much data is written to file)
then inside the download function check if x == 0.
If true then download normally,
Else : resume download using range header
Read Following examples for range header :- source
If the web server supports the range request then you can add the Range header to your request:
Range: bytes=StartPos-StopPos
You will receive the part between StartPos and StopPos. If dont know the StopPos just use:
Range: bytes=StartPos-
So your code would be:
def resume_download(fileurl, resume_byte_position):
resume_header = {'Range': 'bytes=%d-' % resume_byte_position}
return requests.get(fileurl, headers=resume_header, stream=True, verify=False, allow_redirects=True)
Another example :-
https://www.oreilly.com/library/view/python-cookbook/0596001673/ch11s06.html
Also update the variable x after writing each chunk (x = x + chunk_size)
And in the end of your download part, add a "if" statement to check if the file size of downloaded file is same as the file size of file on server (you can get that by requests.header.get('Content-Length'). If file size is not same then you call your download function again.
Resume http file download in java
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
if(ISSUE_DOWNLOAD_STATUS.intValue()==ECMConstant.ECM_DOWNLOADING){
File file=new File(DESTINATION_PATH);
if(file.exists()){
downloaded = (int) file.length();
connection.setRequestProperty("Range", "bytes="+(file.length())+"-");
}
}else{
connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
}
connection.setDoInput(true);
connection.setDoOutput(true);
progressBar.setMax(connection.getContentLength());
in = new BufferedInputStream(connection.getInputStream());
fos=(downloaded==0)? new FileOutputStream(DESTINATION_PATH): new FileOutputStream(DESTINATION_PATH,true);
bout = new BufferedOutputStream(fos, 1024);
byte[] data = new byte[1024];
int x = 0;
while ((x = in.read(data, 0, 1024)) >= 0) {
bout.write(data, 0, x);
downloaded += x;
progressBar.setProgress(downloaded);
}
This is not my code, but it works.
Related Topics
How to Solve the "Double-Checked Locking Is Broken" Declaration in Java
Encoding Url Query Parameters in Java
Variable Length (Dynamic) Arrays in Java
How to Make an Array of Arrays in Java
Turning Off Hibernate Logging Console Output
Sort Arrays of Primitive Types in Descending Order
Singleton Class with Several Different Classloaders
Can Not Find the Tag Library Descriptor for "Http://Java.Sun.Com/Jsp/Jstl/Core"
Using File.Listfiles with Filenameextensionfilter
Classnotfoundexception: Didn't Find Class "Com.Google.Android.Gms.Ads.Adview"
Android Unable to Instantiate Activity: Didn't Find Class on Path
How to Get Elements of Fragments Created by Viewpager in Mainactivity
Android.Content.Res.Resources$Notfoundexception