java 如何恢复中断的下载 - 第 2 部分
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3428102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to resume an interrupted download - part 2
提问by gregS
This is a continuation of my previous questionwhich I posted when I wasn't a registered user. As a refresher, I'm trying to resume the downloading of a large file from my Yahoo! web site server when the download gets interrupted. I previously thought the interruption was due to a 100 second timeout limit (because Yahoo! enforces that time limit on user written scripts). However, when I measured the timing of the download interrupts, I saw that the interrupt timing varies a lot (sometimes the download runs uninterrupted for less than 100 seconds and sometimes up to seven minutes). So I don't know the reason for the timeouts and I'm just trying to work around them.
这是我之前在不是注册用户时发布的问题的延续。作为复习,我正在尝试从 Yahoo! 恢复大文件的下载。下载中断时的网站服务器。我以前认为中断是由于 100 秒超时限制(因为 Yahoo! 对用户编写的脚本强制执行该时间限制)。但是,当我测量下载中断的时间时,我看到中断时间变化很大(有时下载不间断运行不到100秒,有时长达7分钟)。所以我不知道超时的原因,我只是想解决它们。
I tried the suggestion by naikus(thank you) and, according to the dump of http header fields, it appears that my Yahoo! web site server does recognize the "range" property that should allow the download to resume at the offset of the interruption. Unfortunately, although the byte range appears correct in the http header in the resumed connections, the transferred content always restarts at the beginning of the file. (My test file is an array of 50,000 4-byte integers that increments starting at 0. My downloaded file always starts recounting at 0 at every offset at which a download interrupt occurred.)
我尝试了naikus的建议(谢谢),根据 http 头字段的转储,我的 Yahoo! 网站服务器确实识别出“范围”属性,该属性应该允许下载在中断的偏移处恢复。不幸的是,虽然字节范围在恢复连接的 http 标头中显示正确,但传输的内容总是在文件开头重新启动。(我的测试文件是一个包含 50,000 个 4 字节整数的数组,从 0 开始递增。我下载的文件总是在发生下载中断的每个偏移量处从 0 开始重新计数。)
Is there some other http connection property request I should be making to get the Yahoo! server to actually skip to the file offset specified in the header's byte range?Here's the code and what it dumps:
是否有一些其他的 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();
dump:
倾倒:
@ 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
- - -
After the tip from BalusC (thanks), I modified the connection setup but the Yahoo! server continues to reset to the start of the file at each interrupt. Here's the changed code and the resulting dumps:
在 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());
dump:
倾倒:
@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
回答by BalusC
To resume a download, you need to send not only the Rangerequest header, but also the If-Rangerequest header which should contain either the unique file identifier or the file modification timestamp.
要恢复下载,您不仅需要发送Range请求标头,还需要发送If-Range包含唯一文件标识符或文件修改时间戳的请求标头。
If the server returns an ETagresponse header on the initial download, then you should use it in the If-Rangeheader of the subsequent resume requests. Or if it returns a Last-Modifiedresponse header, then you should use it in the If-Rangerequest header instead.
如果服务器ETag在初始下载时返回响应标头,那么您应该If-Range在后续恢复请求的标头中使用它。或者如果它返回一个Last-Modified响应头,那么你应该在If-Range请求头中使用它。
Looking at your logs, the server has sent a Last-Modifiedresponse header. So you should send it back along in an If-Rangeheader of the resume request.
查看您的日志,服务器已发送Last-Modified响应标头。因此,您应该If-Range在恢复请求的标头中将其发送回。
// Initial download.
String lastModified = connection.getHeaderField("Last-Modified");
// ...
// Resume download.
connection.setRequestProperty("If-Range", lastModified);
The server will use this information to verify if you're requesting exactly the same file.
服务器将使用此信息来验证您是否正在请求完全相同的文件。
回答by user1084090
Seems that problem is calling
似乎问题是在调用
input = new BufferedInputStream(url.openStream(), 8192);
instead of
代替
input = new BufferedInputStream(connection.getInputStream(), 8192);
url.openStream()makes another call to openConnection()WITHOUTthe range property.
url.openStream()再次调用openConnection()WITHOUTrange 属性。
回答by Whome
I managed to implement http resume download on my client Java application, trick was to use "If-Range:original_ETag" request header as mentioned in an accepted answer. Here is a full header debug information it may help you understand how resume works.
我设法在我的客户端 Java 应用程序上实现了 http 恢复下载,技巧是使用“If-Range:original_ETag”请求标头,如已接受的答案中所述。这是一个完整的标题调试信息,它可以帮助您了解简历的工作原理。
Normal reply from server, file is read from the start to the end. ETag value is W/"filesize_bytes-modified_utc" metadata from the disk file. It could be something else but thats what Tomcat uses and usually is best for regular file content.
来自服务器的正常回复,文件从头到尾读取。ETag 值是来自磁盘文件的 W/“filesize_bytes-modified_utc”元数据。它可能是别的东西,但这就是 Tomcat 使用的,通常最适合常规文件内容。
HTTP/1.1 200 OK
ETag: W/"19097900-1410863319978"
Last-Modified: Tue, 16 Sep 2014 10:28:39 GMT
Content-Length: 19097900
Content-Type: application/octet-stream
Accept-Ranges: bytes
Server: Apache-Coyote/1.1
Date: Wed, 17 Sep 2014 10:39:52 GMT
Client reads a given chunk from the file by adding Range and If-Range headers. Byte range can be open so server should read starting from given index to the end. Note Content-Length is not the total length of file but this chunk of bytes.
客户端通过添加 Range 和 If-Range 标头从文件中读取给定的块。字节范围可以打开,因此服务器应该从给定的索引开始读取到结束。注意 Content-Length 不是文件的总长度,而是这块字节。
Range: bytes=10000000-
If-Range: W/"19097900-1410863319978"
HTTP/1.1 206 Partial Content
ETag: W/"19097900-1410863319978"
Last-Modified: Tue, 16 Sep 2014 10:28:39 GMT
Content-Length: 9097900
Content-Type: application/octet-stream
Accept-Ranges: bytes
Content-Range: bytes 10000000-19097899/19097900
Server: Apache-Coyote/1.1
Date: Wed, 17 Sep 2014 18:12:36 GMT
If remote file was changed then server should not return 206-PartialContent but regular 200-OK reply. Server should use If-Range value to check for consistency. Some clients like VLCPlayer puts Range field without If-Range value.
如果远程文件已更改,则服务器不应返回 206-PartialContent 而是常规的 200-OK 回复。服务器应该使用 If-Range 值来检查一致性。一些像 VLCPlayer 这样的客户端把 Range 字段放在没有 If-Range 值的地方。
When client is making an initial request without Range+If-Range headers it may add "If-Modified-Since: modified_http_date" header. Server may return 304-NotModified status and client is done. If client gives byteStartIdx>=filesize then server returns 416-RequestedRangeNotSatisfiable.
当客户端在没有 Range+If-Range 标头的情况下发出初始请求时,它可能会添加“If-Modified-Since: modified_http_date”标头。服务器可能会返回 304-NotModified 状态,客户端完成。如果客户端提供 byteStartIdx>=filesize,则服务器返回 416-RequestedRangeNotSatisfiable。
Additional debug dumps to clarify how http-resume works.
额外的调试转储以阐明 http-resume 的工作原理。
Range=bytes=0-0
If-Range=W/"19097900-1410863319978"
HTTP/1.1 206 Partial Content
ETag=W/"19097900-1410863319978"
Date=Fri, 19 Sep 2014 12:53:36 GMT
Content-Length=1
Last-Modified=Tue, 16 Sep 2014 10:28:39 GMT
Content-Type=application/octet-stream
Accept-Ranges=bytes
Server=Apache-Coyote/1.1
Content-Range=bytes 0-0/19097900
- - - - -
Range=bytes=19097800-29097800
If-Range=W/"19097900-1410863319978"
HTTP/1.1 206 Partial Content
ETag=W/"19097900-1410863319978"
Date=Fri, 19 Sep 2014 12:59:24 GMT
Content-Length=100
Last-Modified=Tue, 16 Sep 2014 10:28:39 GMT
Content-Type=application/octet-stream
Accept-Ranges=bytes
Server=Apache-Coyote/1.1
Content-Range=bytes 19097800-19097899/19097900
- - - - - - - -
Range=bytes=19097899-19097899
If-Range=W/"19097900-1410863319978"
HTTP/1.1 206 Partial Content
ETag=W/"19097900-1410863319978"
Date=Fri, 19 Sep 2014 13:01:47 GMT
Content-Length=1
Last-Modified=Tue, 16 Sep 2014 10:28:39 GMT
Content-Type=application/octet-stream
Accept-Ranges=bytes
Server=Apache-Coyote/1.1
Content-Range=bytes 19097899-19097899/19097900

