使用 AFNetworking 下载大文件
Posted
技术标签:
【中文标题】使用 AFNetworking 下载大文件【英文标题】:Downloading large files with AFNetworking 【发布时间】:2012-11-03 08:14:14 【问题描述】:我正在尝试实现大文件的下载并向用户显示当前进度,但阻止:
-[AFURLConnectionOperation setDownloadProgressBlock:]
返回不正确的 bytesRead
和 totalBytesRead
值(它们小于应有的值)。
例如:如果我有一个 90MB 的文件,当它完全下载时,setDownloadProgressBlock:
中的最新块调用给了我大约 30MB 的 totalBytesRead
值。另一方面,如果文件是 2MB 大,最新的块调用会给出正确的 totalBytesRead
2MB 值。
AFNetworking 已从 github 更新到最新版本。 如果 AFNetworking 无法正确执行,我可以使用什么解决方案?
编辑:我已经确定即使文件没有完全下载(并且每次文件相对较大时都会发生这种情况)AFNetworking 调用成功块:
-[AFHTTPRequestOperation setCompletionBlockWithSuccess:failure:]
我就这种情况向here 提出了类似的问题,但没有得到任何答案。
我可以检查下载的代码和实际文件大小,但AFNetworking
没有用于继续部分下载的 API。
【问题讨论】:
试用github.com/steipete/AFDownloadRequestOperation 也支持恢复部分下载 谢谢,但由于某种原因,它对我不起作用。 【参考方案1】:我对 AFNetworking 中的 setDownloadProgressBlock 没有任何问题。
wiki 解释了如何跟踪下载进度: https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ
对于进度跟踪,您不需要 bytesRead
(特定回调中写入的字节数)。
示例代码:
[downloadoperation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead)
float progress = ((float)totalBytesRead) / totalBytesExpectedToRead;
self.progressView.progress = progress;
];
【讨论】:
是的,我明白了,我的代码和你的一样。我只是说 bytesRead 在大文件上也给出了不正确的数字。 你能举个例子吗?正如我所说,您可以忽略bytesRead
,因为它与进度无关。
NSLog(@"%u %llu %llu", bytesRead, totalBytesRead, totalBytesExpectedToRead);
有什么好处? bytesRead 在每个回调中应该或多或少相同。
我在我的问题中添加了一个示例来澄清它。如果我对每个块调用 bytesRead
求和,它将给出等于 totalBytesRead
的值,换句话说就是不正确的值。
AFNetworking 做对了,看源码:github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/… 显然连接取消太早了,可能是磁盘空间不够。我假设您已经设置了一个写入文件的 NSOutputStream。否则会消耗大量内存,ios 可能会因此取消下载。【参考方案2】:
phix23回答了我最初的问题,所以进度块确实没有问题。我正在回答我的编辑。
当成功阻塞时
-[AFHTTPRequestOperation setCompletionBlockWithSuccess:failure:]
被调用,我可以将下载的字节数与预期下载的字节数进行比较(在代码中实现起来并不难)。如果下载的字节数较小 - 我可以从中断的地方继续下载文件。为此,我在NSURLRequest
中使用了Range
http 标头,这里有更多信息:Continue an interrupted download on iPhoneHow to implement resumable file downloads on iPhone SDK
因此,问题并不在于 AFNetworking(NSURLConnection 具有相同的行为),但我认为框架的开发人员可以考虑这种情况。
【讨论】:
~goodfella "我可以将下载的字节数与预期下载的字节数进行比较。(在代码中实现起来并不难)。" 你能用代码详细说明一下吗?您如何获得预期的字节数?我无法从 AFNetworking 中找到这样的 API 您可以在以下类中找到示例代码:github.com/onivem/Download,尤其是在 setCompletionBlocks 方法中。请注意,这个类是为 AFNetworking 编写的,因为它是在 2013 年 5 月。以上是关于使用 AFNetworking 下载大文件的主要内容,如果未能解决你的问题,请参考以下文章