Objective-C 中的暂停/恢复下载
好吧。希望这将是我用 Objective-C 编写的关于下载管理器的最后一篇文章。除了暂停/恢复功能之外,一切似乎都运行良好。我的问题是,当下载尝试从中断处继续时,它将收到的数据附加到文件中,但它似乎仍然试图下载整个文件。这会导致文件比原始文件应有的大小大。这是我用来下载文件的代码。我做错了什么吗?
-(void)start:(unsigned int)fromByte {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:DEFAULT_TIMEOUT];
// Define the bytes we wish to download.
NSString *range = [NSString stringWithFormat:@"bytes=%i-", fromByte];
[request setValue:range forHTTPHeaderField:@"Range"];
// Data should immediately start downloading after the connection is created.
self.urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:TRUE];
if (!self.urlConnection) {
#warning Handle error.
}
}
Alright. Hopefully this will be my last post about the download manager I am writing in Objective-C. Everything seems to work well except the pause/resume functionality. My issue is that when a download tries to continue from where it left off, it appends the data it receives to the file, but it still seems that it's trying to download the entire file. This results in a file that is larger than the original file is supposed to be. Here is the code I am using for downloading files. Am I doing something wrong?
-(void)start:(unsigned int)fromByte {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:DEFAULT_TIMEOUT];
// Define the bytes we wish to download.
NSString *range = [NSString stringWithFormat:@"bytes=%i-", fromByte];
[request setValue:range forHTTPHeaderField:@"Range"];
// Data should immediately start downloading after the connection is created.
self.urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:TRUE];
if (!self.urlConnection) {
#warning Handle error.
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我看到您在请求中指定了 Range 标头。首先要检查的是服务器是否确实接受 Range 请求,方法是检查
connection:didReceiveResponse:
中响应对象(应该是NSHTTPURLResponse
)中的标头适当的内容范围。I see you are specifying the Range header in the request. First thing to check is whether the server is actually honoring the Range request, by checking the headers in the response object (which should be an
NSHTTPURLResponse
) inconnection:didReceiveResponse:
for a proper Content-Range.我终于明白了这一点。事实证明,我的
'getFilesizeInBytes'
方法是从文件的属性中获取NSFileSize
对象,但我直接将其转换为int
>。这导致这个数字比应有的数字大约增加了20倍。我可以使用[@"" intValue]
修复此问题。一旦这个问题被修复,服务器就能够给我以正确字节开始的文件的其余部分。看来我的问题之前不是服务器没有满足我的请求,而是它无法满足我的请求,因为我请求的数据远远超出了我的要求。文件的最后一个字节。I finally figured this out. It turns out that the
'getFilesizeInBytes'
method I had was get theNSFileSize
object from the file's attributes, but I was directly casting this to anint
. This caused the number to be about 20 times larger than it should have been. I was able to fix this by using[@"" intValue]
. Once this was fixed, the servers were able to give me the rest of the file starting with the correct byte. It seems that before my issue was not that the server wasn't honoring my request, but that it couldn't honor my request due to me requesting data that was well beyond the final byte of the file.NSURLConnection 不支持暂停/恢复。您可以通过停止请求来模拟它,然后在恢复时使用
Range
标头发出对其余内容的请求。为此需要 HTTP 服务器的某些支持,但不能保证。看起来您所面临的问题是服务器缺乏支持。
然而,大多数下载管理器在套接字之上实现自己的 HTTP 堆栈。
There's no support for pause/resume in NSURLConnection. You can emulate it by stopping the request, then issuing a request for the rest of the content with a
Range
header on resume. Some support from the HTTP server is required for that, and is not guaranteed.Looks like lack of support at the server is what you're facing.
Most download managers, however, implement their own HTTP stack on top of sockets.