我正试图通过以下方式解决从Web服务接收大量数据的一般情况:
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
对于小数据,我只使用:
[webData appendData:data];
最后,在:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
我使用输出流将其写入我的文件。
当数据庞大时,几MB的数据怎么样?在这种情况下,最好将connection:didReceiveData:
中的数据多次转储到同一个文件中。使用NSFileHandle
听起来很简单,但在考虑异步/非阻塞UI的同时进行读写同步并不简单(至少对我而言)。
知道这个案例的好方法是什么?
我想使用NSThread
,每次排队块大小。对此有没有更好/更简单的方法?
答案 0 :(得分:2)
你知道,我实际上已经为这段时间做了一个课(非ARC,但它仍然可以工作)可用here
使用示例:
// in init
RJRStreamWriter myWriter = [[RJRStreamWriter alloc] initWithLocalFile:@"path/to/my/file" andAppend:NO];
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
static dispatch_queue_t asyncQueue;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
asyncQueue = dispatch_queue_create("asyncQueue", NULL);
});
dispatch_async(asyncQueue, ^{
// this method is optimized, and aggregates NSOutputStream, NSMutableData, and NSFileHandle
[myWriter writeData:data];
});
}
答案 1 :(得分:1)
首先,几个MB并不大。以相同的方式对几个MB进行操作绝对没问题。但是,如果您确实希望在收到数据时写入文件,则可以使用NSFileHandle
。创建一个然后向其写入数据,然后在要将数据刷新到磁盘时调用它上面的synchronizeFile
。你可以在说出每10MB写完一些内容之后给synchronizeFile
打电话(显然最后也是这样)。
所以例如:
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filename];
...
[fileHandle writeData:dataComeInFromURLConnection];
...
[fileHandle synchronizeFile];