Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement pause/resume in file downloading

Tags:

I'm trying to implement pause/resume in my download manager, I search the web and read several articles and change my code according them but resume seems not working correctly, Any ideas?

                if (!downloadPath.exists()) 
                    downloadPath.mkdirs(); 

                if (outputFileCache.exists())
                {
                    downloadedSize = outputFileCache.length();
                    connection.setAllowUserInteraction(true);
                    connection.setRequestProperty("Range", "bytes=" + downloadedSize + "-");
                    connection.setConnectTimeout(14000);
                    connection.connect();
                    input = new BufferedInputStream(connection.getInputStream());
                    output = new FileOutputStream(outputFileCache, true);
                    input.skip(downloadedSize); //Skip downloaded size
                }
                else
                {
                    connection.setConnectTimeout(14000);
                    connection.connect();
                    input = new BufferedInputStream(url.openStream());
                    output = new FileOutputStream(outputFileCache);
                }

                fileLength = connection.getContentLength();                 


                byte data[] = new byte[1024];
                int count = 0;
                int __progress = 0;
                long total = downloadedSize;

                while ((count = input.read(data)) != -1 && !this.isInterrupted()) 
                {
                    total += count;
                    output.write(data, 0, count);
                    __progress = (int) (total * 100 / fileLength);

                }
                output.flush();
                output.close();
                input.close();
like image 512
NullPointer Avatar asked Mar 11 '13 21:03

NullPointer


People also ask

How do you pause a resume and download it?

Continue Paused Downloads Alternatively, select the desired file in DAP's main menu and click the Pause button at the top of DAP's main window. Click the Pause All button to stop all current downloads. You can choose whether to resume just one specific file or all paused downloads at once.

How can I pause my resume and download from Play Store?

You cannot actually pause the download. However, you can pause it by cutting off Internet access to Play Store, so it waits for the internet to come back online. You might find some 3rd party apps which can do this for you.

Can I resume a download if I shut down my computer?

If you just use a download manager such as JDownloader (multiplatform) you'll be able to resume the download after shutdown provided the server you are downloading from supports it. Some websites, due to server software, just do not support resuming downloads and they can't start transmitting midway through a file.


2 Answers

Okay problem fixed, here is my code for other users who wants to implement pause/resume:

        if (outputFileCache.exists())
        {
            connection.setAllowUserInteraction(true);
            connection.setRequestProperty("Range", "bytes=" + outputFileCache.length() + "-");
        }

        connection.setConnectTimeout(14000);
        connection.setReadTimeout(20000);
        connection.connect();

        if (connection.getResponseCode() / 100 != 2)
            throw new Exception("Invalid response code!");
        else
        {
            String connectionField = connection.getHeaderField("content-range");

            if (connectionField != null)
            {
                String[] connectionRanges = connectionField.substring("bytes=".length()).split("-");
                downloadedSize = Long.valueOf(connectionRanges[0]);
            }

            if (connectionField == null && outputFileCache.exists())
                outputFileCache.delete();

            fileLength = connection.getContentLength() + downloadedSize;
            input = new BufferedInputStream(connection.getInputStream());
            output = new RandomAccessFile(outputFileCache, "rw");
            output.seek(downloadedSize);

            byte data[] = new byte[1024];
            int count = 0;
            int __progress = 0;

            while ((count = input.read(data, 0, 1024)) != -1 
                    && __progress != 100) 
            {
                downloadedSize += count;
                output.write(data, 0, count);
                __progress = (int) ((downloadedSize * 100) / fileLength);
            }

            output.close();
            input.close();
       }
like image 168
NullPointer Avatar answered Sep 19 '22 13:09

NullPointer


It is impossible to tell what is wrong without some more information, however things to note:

  1. You must make a HTTP/1.1 request (it's hard to tell from your sample code)
  2. The server must support HTTP/1.1
  3. The server will tell you what it supports with an Accept-Ranges header in the response
  4. If-Range should be the etag the server gave you for the resource, not the last modified time

You should check your range request with something simple to test the origin actually supports the Range request first (like curl or wget )

like image 24
stringy05 Avatar answered Sep 22 '22 13:09

stringy05