Search code examples
javahttpdownloadnioresume

Resume an interrupted download using nio pattern


I have searched the answser of my question a lot of times without find any one... Then im here and i hope someone will able to help me !

My code here:

URLConnection connection = new URL("http://foo.bar/bar.b").openConnection();
File file = new File(connection.getURL().getPath().substring(1));

FileChannel download = new FileOutputStream(file).getChannel();

long totalBytes = connection.getContentLengthLong(), start = System.nanoTime(),
        time = System.nanoTime(), between, length, elapsed, data = 0;
int percent, totalPercent;

ReadableByteChannel channel = Channels.newChannel(connection.getInputStream());

while(download.transferFrom(channel, file.length(), 1024) > 0) {
    between = System.nanoTime() - time;

    if(between < 1000000000) continue;

    length = file.length();
    elapsed = System.nanoTime() - start;

    percent = (int) ((double) ((double)length / ((double)totalBytes == 0.0 ? 1.0 : (double)totalBytes) * 100.0));
    totalPercent = (int) (((double)downloaded / (double)releases.getUpdateLength()) * 100.0);

    manager.getForm().updateCurrentPercentage(
            percent,
            increment,
            files.size());

    manager.getForm().updateTotalPercentage(totalPercent,
            FileUtils.getTimeAsString(((elapsed * totalBytes / length) - elapsed)/1000000),
            FileUtils.getReadableSize(length - data));

    time = System.nanoTime();
    data = length;
}

The current code works & downloads perfectly, but when i interrupt the application & restart it, (for example when the download was at 56%), the file restart from 0..

So i was testing to debug & i found that

FileChannel download = new FileOutputStream(file).getChannel();

This line remove the content of my local file (which was interrupted), & its length restart at 0. Why ?

I was wondering if i have to use Http properties with that methods or not. I tried a lot of ways but nothing seems work..


Solution

  • Okay i had just to add this line:

    if(file.exists())
        connection.setRequestProperty("Range", "bytes=" + file.length() + "-");
    

    and replace the current constructor FileOutputStream by

    FileChannel download = new FileOutputStream(file, file.exists()).getChannel();
    

    It works :)