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.
I guess the problem you are facing is calling url.openStream()
after url.openConnection()
.
url.openStream()
is equivalent to url.openConnection().getInputStream()
. Hence, you are requesting the url twice. Particularly the second time, it is not specifying the range property. Therefore download always starts at the beginning.
You should replace url.openStream()
with connection.getInputStream()
.
This is what I am using to download the file in chunk Updating the UI with progress.
/* * @param callback = To update the UI with appropriate action * @param fileName = Name of the file by which downloaded file will be saved. * @param downloadURL = File downloading URL * @param filePath = Path where file will be saved * @param object = Any object you want in return after download is completed to do certain operations like insert in DB or show toast */public void startDownload(final IDownloadCallback callback, String fileName, String downloadURL, String filePath, Object object) { callback.onPreExecute(); // Callback to tell that the downloading is going to start int count = 0; File outputFile = null; // Path where file will be downloaded try { File file = new File(filePath); file.mkdirs(); long range = 0; outputFile = new File(file, fileName); /** * Check whether the file exists or not * If file doesn't exists then create the new file and range will be zero. * But if file exists then get the length of file which will be the starting range, * from where the file will be downloaded */ if (!outputFile.exists()) { outputFile.createNewFile(); range = 0; } else { range = outputFile.length(); } //Open the Connection URL url = new URL(downloadURL); URLConnection con = url.openConnection(); // Set the range parameter in header and give the range from where you want to start the downloading con.setRequestProperty("Range", "bytes=" + range + "-"); /** * The total length of file will be the total content length given by the server + range. * Example: Suppose you have a file whose size is 1MB and you had already downloaded 500KB of it. * Then you will pass in Header as "Range":"bytes=500000". * Now the con.getContentLength() will be 500KB and range will be 500KB. * So by adding the two you will get the total length of file which will be 1 MB */ final long lenghtOfFile = (int) con.getContentLength() + range; FileOutputStream fileOutputStream = new FileOutputStream(outputFile, true); InputStream inputStream = con.getInputStream(); byte[] buffer = new byte[1024]; long total = range; /** * Download the save the content into file */ while ((count = inputStream.read(buffer)) != -1) { total += count; int progress = (int) (total * 100 / lenghtOfFile); EntityDownloadProgress entityDownloadProgress = new EntityDownloadProgress(); entityDownloadProgress.setProgress(progress); entityDownloadProgress.setDownloadedSize(total); entityDownloadProgress.setFileSize(lenghtOfFile); callback.showProgress(entityDownloadProgress); fileOutputStream.write(buffer, 0, count); } //Close the outputstream fileOutputStream.close(); // Disconnect the Connection if (con instanceof HttpsURLConnection) { ((HttpsURLConnection) con).disconnect(); } else if (con instanceof HttpURLConnection) { ((HttpURLConnection) con).disconnect(); } inputStream.close(); /** * If file size is equal then return callback as success with downlaoded filepath and the object * else return failure */ if (lenghtOfFile == outputFile.length()) { callback.onSuccess(outputFile.getAbsolutePath(), object); } else { callback.onFailure(object); } } catch (Exception e) { e.printStackTrace(); callback.onFailure(object); }}
interface IDownloadCallback {
void onPreExecute(); // Callback to tell that the downloading is going to start void onFailure(Object o); // Failed to download file void onSuccess(String path, Object o); // Downloaded file successfully with downloaded path void showProgress(EntityDownloadProgress entityDownloadProgress); // Show progress}
public class EntityDownloadProgress {
int progress; // range from 1-100 long fileSize;// Total size of file to be downlaoded long downloadedSize; // Size of the downlaoded file public void setProgress(int progress) {this.progress = progress;} public void setFileSize(long fileSize) {this.fileSize = fileSize;} public void setDownloadedSize(long downloadedSize) {this.downloadedSize = downloadedSize;}}