在文件下载中实施暂停/恢复

2022-09-02 09:53:11

我正在尝试在我的下载管理器中实现暂停/恢复,我搜索网络并阅读了几篇文章并根据它们更改我的代码,但恢复似乎无法正常工作,有什么想法吗?

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

答案 1

好的,问题已修复,这是我为想要实现暂停/恢复的其他用户提供的代码:

        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();
       }

答案 2

如果没有更多的信息,就不可能说出出了什么问题,但是要注意的是:

  1. 您必须发出 HTTP/1.1 请求(很难从示例代码中看出)
  2. 服务器必须支持 HTTP/1.1
  3. 服务器将通过响应中的接受范围标头告诉您它支持的内容
  4. If-Range 应该是服务器为资源提供的 etag,而不是上次修改时间

您应该使用简单的东西来检查您的范围请求,以测试原点是否首先支持Range请求(如curl或wget)