Resume http file download in java

2019-01-02 19:11发布

URL url = new URL("http://download.thinkbroadband.com/20MB.zip");

URLConnection connection = url.openConnection();
File fileThatExists = new File(path); 
OutputStream output = new FileOutputStream(path, true);
connection.setRequestProperty("Range", "bytes=" + fileThatExists.length() + "-");

connection.connect();

int lenghtOfFile = connection.getContentLength();

InputStream input = new BufferedInputStream(url.openStream());
byte data[] = new byte[1024];

long total = 0;

while ((count = input.read(data)) != -1) {
    total += count;

    output.write(data, 0 , count);
}

in this code I try to resume download. Target file is 20MB. But when I stop download on 10mb, then contunue, I get file with filesize 30MB. It seems that it continue writing to file, but cant partly download from server. Wget -c works great with this file. How can I resume file download?

7条回答
梦该遗忘
2楼-- · 2019-01-02 19:49

Check out this thread which has a problem similar to yours. If wget is working, then the server clearly supports resuming downloads. It looks like you're not setting the If-Range header as mentioned in the accepted answer of the above link. ie. add:

// Initial download.
String lastModified = connection.getHeaderField("Last-Modified");

// ...

// Resume download.
connection.setRequestProperty("If-Range", lastModified); 
查看更多
高级女魔头
3楼-- · 2019-01-02 19:54

I have a way for your code to work.

  1. First, check if the file exits or not
  2. If the file exists, set the connection:

    connection.setRequestProperty("Range", "bytes=" + bytedownloaded + "-");
    
  3. If file does not exist, do the same download in a new file.

查看更多
余生无你
4楼-- · 2019-01-02 20:03

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().

查看更多
明月照影归
5楼-- · 2019-01-02 20:04
 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.

查看更多
爱死公子算了
6楼-- · 2019-01-02 20:05

Since the question is tagged with Android: Have you tried using DownloadManager. It handles all this stuff nicely for you.

查看更多
永恒的永恒
7楼-- · 2019-01-02 20:08

How about this?

public static void download(DownloadObject object) throws IOException{
    String downloadUrl = object.getDownloadUrl();
    String downloadPath = object.getDownloadPath();
    long downloadedLength = 0;

    File file = new File(downloadPath);
    URL url = new URL(downloadUrl);

    BufferedInputStream inputStream = null;
    BufferedOutputStream outputStream = null;

    URLConnection connection = url.openConnection();

    if(file.exists()){
        downloadedLength = file.length();
        connection.setRequestProperty("Range", "bytes=" + downloadedLength + "-");
        outputStream = new BufferedOutputStream(new FileOutputStream(file, true));

    }else{
        outputStream = new BufferedOutputStream(new FileOutputStream(file));

    }

    connection.connect();

    inputStream = new BufferedInputStream(connection.getInputStream());


    byte[] buffer = new byte[1024*8];
    int byteCount;

    while ((byteCount = inputStream.read(buffer)) != -1){
        outputStream.write(buffer, 0, byteCount);
        break;

    }

    inputStream.close();
    outputStream.flush();
    outputStream.close();

}

Used break; to test the code.. ;)

查看更多
登录 后发表回答