首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用NSURLSessionDownloadTask计算超大型文件的NSURLSessionDownloadTask

用NSURLSessionDownloadTask计算超大型文件的NSURLSessionDownloadTask
EN

Stack Overflow用户
提问于 2014-03-30 00:15:44
回答 2查看 608关注 0票数 0

NSURLConnection可用于实时计算md5:

代码语言:javascript
复制
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
    // theData is a small piece

NSURLSessionDownloadTask是NSURLConnection的“升级”。但是,在下载完整个文件之后,我们如何在不重新读取整个文件的情况下检查md5呢?它的接口类似于:

代码语言:javascript
复制
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request
                                                     completionHandler:
^(NSURL *location, NSURLResponse *response, NSError *error) {
    // the whole file is downloaded and saved at location.
}];

这里的关键要求是内存占用少,文件必须完全下载。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-30 00:34:24

如果您希望数据以较小的NSData片段到达,您可以像对connection:didReceiveData:那样一点一点地检查并附加到更大的NSMutableData中,请请求一个数据任务而不是一个下载任务。

您可以调用dataTaskWithRequest:,提供一个委托,并启动数据任务(使用resume) --委托接收URLSession:dataTask:didReceiveData:,就像以前的NSURLConnection时代一样。

下面是一个完整的工作示例(只是我不告诉您在数据到达时该如何处理):

代码语言:javascript
复制
- (NSURLSession*) configureSession {
    NSURLSessionConfiguration* config =
    [NSURLSessionConfiguration ephemeralSessionConfiguration];
    config.allowsCellularAccess = NO;
    NSURLSession* session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    return session;
}

- (IBAction) doHTTP: (id) sender {
    if (!self.session)
        self.session = [self configureSession];

    NSString* s = // some URL string
    NSURL* url = [NSURL URLWithString:s];
    NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:url];
    NSURLSessionDataTask* task = [[self session] dataTaskWithRequest:req];
    self.task = task;
    [task resume];
}

-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    NSLog(@"received %lu bytes of data", (unsigned long)data.length);
    // do something with the data here!
}

-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    NSLog(@"completed; error: %@", error);
}
票数 2
EN

Stack Overflow用户

发布于 2014-03-30 02:16:23

正如Matt所说,您可以使用一个数据任务,它允许您在下载数据时轻松查看数据。

然而,如果你想观察一个下载任务,你可以完成类似的事情,如果你愿意承担一些小的风险。

我肯定我会得到一百万的选票,但请记住.当你需要一个螺丝刀,而你只有一个锤子,你翻转锤子,并使用它作为螺丝刀.或者钉在螺丝上会变成钉子.

首先,我认为API坏了。代表们至少应提供这两件事中的一件。如果你同意的话,发个雷达。委托应该提供临时文件(我认为应该保持不透明),或者应该提供用URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:编写的URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite: --这是正确的答案。

不管怎么说,如果你愿意使用无文档的非官方的方法.

临时文件存储在Library/Caches/com.apple.nsnetworkd/中,因此您可以轻松地查看其中并确定哪些文件被用作临时目标。

或者,您也可以通过取消使用下载的cancelByProducingResumeData:来确定临时文件,然后取消对简历数据blob的存档--简历数据blob当前是一个存档字典--并从字典中获取文件路径。然后,您可以继续下载,知道正在使用哪个临时文件进行下载。

无论如何,一旦您有了该文件,在您的URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:中,您就可以从该文件中读取最近编写的块。

现在,尽管如此,您可能希望只使用一个数据任务,因为它将正式为您提供它刚刚下载的数据.但是,如果您必须进行后台下载,可以利用此黑客获取下载到文件中的数据--这必须是下载任务。

您可能遇到的一个问题是,文件IO可能会被缓冲,因此实际刷新的内容(以及可用的单独文件描述符)可能与委托方法中报告的内容不同。您可能只需要跟踪您读取的最后一个字节,而在该委托中,只需从那里读取到文件的当前末尾.

您的里程数肯定会有所不同,但它将使您在将数据写入文件时访问该数据。

您必须对URLSession:downloadTask:didFinishDownloadingToURL:做同样的事情才能获得最后的数据。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22738652

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档