如何恢复中断的下载 - 第 2 部分

2022-09-02 03:44:02

这是我在不是注册用户时发布的上一个问题的延续。作为复习,当下载中断时,我正在尝试从我的Yahoo网站服务器恢复下载大文件。我以前认为中断是由于100秒超时限制造成的(因为Yahoo!对用户编写的脚本强制执行该时间限制)。但是,当我测量下载中断的时间时,我发现中断时间变化很大(有时下载不间断运行不到100秒,有时长达七分钟)。所以我不知道超时的原因,我只是试图解决它们。

我尝试了naikus的建议(谢谢),根据http标头字段的转储,似乎我的Yahoo!网站服务器确实识别了“range”属性,该属性应该允许下载在中断的偏移处恢复。遗憾的是,尽管字节范围在恢复的连接的 http 标头中显示正确,但传输的内容始终在文件开头重新启动。(我的测试文件是一个包含 50,000 个 4 字节整数的数组,从 0 开始递增。我下载的文件总是在发生下载中断的每个偏移量处以 0 开始重新计数。

我是否应该提出其他一些 http 连接属性请求,以使 Yahoo! 服务器实际跳到标头字节范围内指定的文件偏移量?下面是代码及其转储的内容:

         // Setup connection.
         URL url = new URL(strUrl[0]);
         URLConnection connection = url.openConnection();
         downloaded = Integer.parseInt(strUrl[3]);
         if (downloaded > 0) {
             connection.setRequestProperty("Range", "bytes="+downloaded+"-");
             connection.connect();
             fileLength = mDownloadFileLength;
             Log.d("AsyncDownloadFile", 
                 "new download seek: " + downloaded +
                 "; lengthFile: " + fileLength);
         }
         else {
             connection.connect();
             downloaded = 0;
             fileLength = connection.getContentLength();
             mDownloadFileLength = fileLength;
         }
         Map<String, List<String>> map = connection.getHeaderFields();
         Log.d("AsyncDownloadFile", "header fields: " + map.toString());

         // Setup streams and buffers.
         input = new BufferedInputStream(url.openStream(), 8192);
         outFile = new RandomAccessFile(strUrl[1], "rw");
         if (downloaded > 0)  
             outFile.seek(downloaded);
         byte data[] = new byte[1024];

         // Download file.
         for (int count=0, i=0; (count=input.read(data, 0, 1024)) != -1; i++) { 
             outFile.write(data, 0, count);
             downloaded += count; 
             if (downloaded >= fileLength)
                 break;

             // Display progress.
             Log.d("AsyncDownloadFile", "bytes: " + downloaded);
             if ((i%10) == 0)
                 publishProgress((int)(downloaded*100/fileLength));
             if (mFlagDisableAsyncTask) {
                 downloaded = 0;
                 break;
             }
         }

         // Close streams.
         outFile.close();
         input.close();

转 储:

@ 4:08:24  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[2000000], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:08:33 GMT]}  
D/AsyncDownloadFile( 2372): bytes: 1024  
D/AsyncDownloadFile( 2372): bytes: 1033  
D/AsyncDownloadFile( 2372): bytes: 2057  
D/AsyncDownloadFile( 2372): bytes: 2493  
D/AsyncDownloadFile( 2372): bytes: 3517  
D/AsyncDownloadFile( 2372): bytes: 3953  

.
.
.

@ 4:13:25  
D/AsyncDownloadFile( 2372): bytes: 386473  
D/AsyncDownloadFile( 2372): bytes: 387497  
D/AsyncDownloadFile( 2372): bytes: 387933  
D/AsyncDownloadFile( 2372): new download seek: 387933; lengthFile: 2000000  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[1612067], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:13:29 GMT], co
ntent-range=[bytes 387933-1999999/2000000]}  
D/AsyncDownloadFile( 2372): bytes: 388957  
D/AsyncDownloadFile( 2372): bytes: 389981  
D/AsyncDownloadFile( 2372): bytes: 390409  
D/AsyncDownloadFile( 2372): bytes: 391433  
D/AsyncDownloadFile( 2372): bytes: 391869  
D/AsyncDownloadFile( 2372): bytes: 392893  

.
.
.

@ 4:18:45  
D/AsyncDownloadFile( 2372): bytes: 775413  
D/AsyncDownloadFile( 2372): bytes: 775849  
D/AsyncDownloadFile( 2372): bytes: 776873  
D/AsyncDownloadFile( 2372): bytes: 777309  
D/AsyncDownloadFile( 2372): new download seek: 777309; lengthFile: 2000000  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[1222691], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:18:54 GMT], co
ntent-range=[bytes 777309-1999999/2000000]}  
D/dalvikvm( 2372): GC_FOR_MALLOC freed 11019 objects / 470560 bytes in 155ms  
D/AsyncDownloadFile( 2372): bytes: 778333  
D/AsyncDownloadFile( 2372): bytes: 779357  
D/AsyncDownloadFile( 2372): bytes: 779790  
D/AsyncDownloadFile( 2372): bytes: 780814  
D/AsyncDownloadFile( 2372): bytes: 781250  
D/AsyncDownloadFile( 2372): bytes: 782274  

.
.
.

@ 4:23:45  
D/AsyncDownloadFile( 2372): bytes: 1163334  
D/AsyncDownloadFile( 2372): bytes: 1163770  
D/AsyncDownloadFile( 2372): bytes: 1164794  
D/AsyncDownloadFile( 2372): bytes: 1165230  
D/AsyncDownloadFile( 2372): new download seek: 1165230; lengthFile: 2000000  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[834770], age=[0], server
=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:23:47 GMT], con
tent-range=[bytes 1165230-1999999/2000000]}  
D/AsyncDownloadFile( 2372): bytes: 1166246  
D/AsyncDownloadFile( 2372): bytes: 1167270  
D/AsyncDownloadFile( 2372): bytes: 1167706  
D/AsyncDownloadFile( 2372): bytes: 1168730  
D/AsyncDownloadFile( 2372): bytes: 1169754  
D/AsyncDownloadFile( 2372): bytes: 1170778  

.
.
.

@ 4:30:25  
D/AsyncDownloadFile( 2372): bytes: 1551255  
D/AsyncDownloadFile( 2372): bytes: 1551691  
D/AsyncDownloadFile( 2372): bytes: 1552715  
D/AsyncDownloadFile( 2372): bytes: 1553151  
D/AsyncDownloadFile( 2372): new download seek: 1553151; lengthFile: 2000000  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[446849], age=[0], server
=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:30:44 GMT], con
tent-range=[bytes 1553151-1999999/2000000]}  
D/AsyncDownloadFile( 2372): bytes: 1554167  
D/AsyncDownloadFile( 2372): bytes: 1554184  
D/AsyncDownloadFile( 2372): bytes: 1555208  
D/AsyncDownloadFile( 2372): bytes: 1555644  
D/AsyncDownloadFile( 2372): bytes: 1556668  
D/AsyncDownloadFile( 2372): bytes: 1557104  

.
.
.

@ 4:37:10  
D/AsyncDownloadFile( 2372): bytes: 1939188  
D/AsyncDownloadFile( 2372): bytes: 1939624  
D/AsyncDownloadFile( 2372): bytes: 1940648  
D/AsyncDownloadFile( 2372): bytes: 1941084  
D/AsyncDownloadFile( 2372): new download seek: 1941084; lengthFile: 2000000  
D/dalvikvm( 2372): GC_FOR_MALLOC freed 13701 objects / 604600 bytes in 128ms
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[58916], age=[0], server=
[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:37:16 GMT], cont
ent-range=[bytes 1941084-1999999/2000000]}  
D/AsyncDownloadFile( 2372): bytes: 1942108  
D/AsyncDownloadFile( 2372): bytes: 1942117  
D/AsyncDownloadFile( 2372): bytes: 1943141  
D/AsyncDownloadFile( 2372): bytes: 1943577  
D/AsyncDownloadFile( 2372): bytes: 1944601  
D/AsyncDownloadFile( 2372): bytes: 1945037  

.
.
.

@ 4:38:30  
D/AsyncDownloadFile( 2372): bytes: 1993217  
D/AsyncDownloadFile( 2372): bytes: 1994241  
D/AsyncDownloadFile( 2372): bytes: 1994677  
D/AsyncDownloadFile( 2372): bytes: 1995701  
D/AsyncDownloadFile( 2372): bytes: 1996137  
D/AsyncDownloadFile( 2372): bytes: 1997161  
D/AsyncDownloadFile( 2372): bytes: 1997597  
D/AsyncDownloadFile( 2372): bytes: 1998621  
D/AsyncDownloadFile( 2372): bytes: 1999057  
D/onPostExecute( 2372): download: unsuccessful  

- - -  

在BalusC的提示(谢谢)之后,我修改了连接设置,但Yahoo!服务器在每次中断时都会继续重置为文件的开头。下面是更改的代码和生成的转储:

            // Setup connection.
            URL url = new URL(strUrl[0]);
            URLConnection connection = url.openConnection();
            downloaded = Integer.parseInt(strUrl[3]);
            if (downloaded == 0) {
                connection.connect();
                strLastModified = connection.getHeaderField("Last-Modified");
                fileLength = connection.getContentLength();
                mDownloadFileLength = fileLength;
            }
            else {
                connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
                connection.setRequestProperty("If-Range", strLastModified);
                connection.connect();
                fileLength = mDownloadFileLength;
                Log.d("AsyncDownloadFile", 
                        "new download seek: " + downloaded +
                        "; lengthFile: " + fileLength);
            }
            map = connection.getHeaderFields();
            Log.d("AsyncDownloadFile", "header fields: " + map.toString());

转 储:

@12:36:40 started  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.c
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTP
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA P
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-m
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[2000000], age=[0], serv
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:36:56 GMT]}  
D/AsyncDownloadFile(  413): bytes: 1024  
D/AsyncDownloadFile(  413): bytes: 2048  
D/AsyncDownloadFile(  413): bytes: 2476  
D/AsyncDownloadFile(  413): bytes: 3500  
D/AsyncDownloadFile(  413): bytes: 3936  

...

@12:39:20 interrupted  
D/AsyncDownloadFile(  413): bytes: 388068  
D/AsyncDownloadFile(  413): bytes: 389092  
D/AsyncDownloadFile(  413): bytes: 389376  
D/AsyncDownloadFile(  413): new download seek: 389376; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[1610624], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:39:21 GMT], co
ntent-range=[bytes 389376-1999999/2000000]}  
D/AsyncDownloadFile(  413): bytes: 390400  
D/AsyncDownloadFile(  413): bytes: 390409  
D/AsyncDownloadFile(  413): bytes: 391433  
D/AsyncDownloadFile(  413): bytes: 391869  

...

@12:44:10 interrupted  
D/AsyncDownloadFile(  413): bytes: 775413  
D/AsyncDownloadFile(  413): bytes: 775849  
D/AsyncDownloadFile(  413): bytes: 776873  
D/AsyncDownloadFile(  413): bytes: 777309  
D/AsyncDownloadFile(  413): new download seek: 777309; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[1222691], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:44:20 GMT], co
ntent-range=[bytes 777309-1999999/2000000]}  
D/dalvikvm(  413): GC_FOR_MALLOC freed 10869 objects / 465664 bytes in 122ms  
D/AsyncDownloadFile(  413): bytes: 778333  
D/AsyncDownloadFile(  413): bytes: 778342  
D/AsyncDownloadFile(  413): bytes: 779366  
D/AsyncDownloadFile(  413): bytes: 779802  

...

@12:49:30 interrupted  
D/AsyncDownloadFile(  413): bytes: 1163782  
D/AsyncDownloadFile(  413): bytes: 1164806  
D/AsyncDownloadFile(  413): bytes: 1165242  
D/AsyncDownloadFile(  413): new download seek: 1165242; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[834758], age=[0], server
=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:49:43 GMT], con
tent-range=[bytes 1165242-1999999/2000000]}  
D/AsyncDownloadFile(  413): bytes: 1166266  
D/AsyncDownloadFile(  413): bytes: 1167290  
D/AsyncDownloadFile(  413): bytes: 1167718  
D/AsyncDownloadFile(  413): bytes: 1168742  

...

@12:55:30 interrupted  
D/AsyncDownloadFile(  413): bytes: 1552722  
D/AsyncDownloadFile(  413): bytes: 1553158  
D/AsyncDownloadFile(  413): bytes: 1554182  
D/AsyncDownloadFile(  413): bytes: 1554618  
D/AsyncDownloadFile(  413): new download seek: 1554618; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[445382], age=[0], server
=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:55:39 GMT], con
tent-range=[bytes 1554618-1999999/2000000]}  
D/AsyncDownloadFile(  413): bytes: 1555642  
D/AsyncDownloadFile(  413): bytes: 1556666  
D/AsyncDownloadFile(  413): bytes: 1557094  
D/AsyncDownloadFile(  413): bytes: 1558118  

...

@12:57:20 interrupted  
D/AsyncDownloadFile(  413): bytes: 1941834  
D/AsyncDownloadFile(  413): bytes: 1942858  
D/AsyncDownloadFile(  413): bytes: 1943882  
D/AsyncDownloadFile(  413): bytes: 1943994  
D/AsyncDownloadFile(  413): new download seek: 1943994; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[56006], age=[0], server=
[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:57:15 GMT], cont
ent-range=[bytes 1943994-1999999/2000000]}  
D/dalvikvm(  413): GC_FOR_MALLOC freed 13617 objects / 602200 bytes in 165ms  
D/AsyncDownloadFile(  413): bytes: 1945018  
D/AsyncDownloadFile(  413): bytes: 1946042  
D/AsyncDownloadFile(  413): bytes: 1946470  
D/AsyncDownloadFile(  413): bytes: 1947494  

...

@12:58:10 finished  
D/AsyncDownloadFile(  413): bytes: 1996103  
D/AsyncDownloadFile(  413): bytes: 1997127  
D/AsyncDownloadFile(  413): bytes: 1997563  
D/AsyncDownloadFile(  413): bytes: 1998587  
D/AsyncDownloadFile(  413): bytes: 1999023  
D/onPostExecute(  413): downloaded: unsuccessful  

答案 1

要恢复下载,您不仅需要发送 Range 请求标头,还需要发送 If-Range 请求标头,该标头应包含唯一文件标识符或文件修改时间戳。

如果服务器在初始下载时返回 ETag 响应标头,则应在后续恢复请求的标头中使用它。或者,如果它返回上次修改的响应标头,则应在请求标头中使用它。If-RangeIf-Range

查看日志,服务器已发送响应标头。因此,您应该在简历请求的标头中将其发送回去。Last-ModifiedIf-Range

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

// ...

// Resume download.
connection.setRequestProperty("If-Range", lastModified); 

服务器将使用此信息来验证您是否请求的文件完全相同。


答案 2

似乎问题出在打电话

input = new BufferedInputStream(url.openStream(), 8192);

而不是

input = new BufferedInputStream(connection.getInputStream(), 8192);

url.openStream()WITHOUT 范围属性进行另一次调用。openConnection()


推荐