[英]Writing a large amount of data from a web service to a file in chunks
I'm trying to solve the general situation of receiving a big chunk of data from web services via: 我正在尝试通过以下方法解决从Web服务接收大量数据的一般情况:
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
For small data, I just use: 对于小数据,我只使用:
[webData appendData:data];
and at the end, in: 最后,在:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
I write it to my file using an output stream. 我使用输出流将其写入我的文件。
What about when the data is huge, a couple of MBs of data? 如果数据量巨大,只有几MB的数据呢? In this case, it would be better to dump data in
connection:didReceiveData:
several times to the same file. 在这种情况下,最好将
connection:didReceiveData:
数据多次转储到同一文件中。 It sounds easy, using NSFileHandle
, but syncing for read and write while considering async/non-blocking UI is not straightforward (at least for me). 使用
NSFileHandle
听起来很容易,但是在考虑异步/非阻塞UI的同时进行读写同步并不容易(至少对我而言)。
Any idea what would be a good approach for this case? 知道这个案例有什么好的方法吗? I was thinking to use
NSThread
, queueing the chunk size each time. 我当时正在考虑使用
NSThread
,每次都对块大小进行排队。 Is there any better/easier approach for this? 有没有更好/更简便的方法呢?
You know, I actually made a class for this a while back (non-ARC, but it still should work) available here 您知道,我实际上为此做了一个类(非ARC,但仍然可以使用),可在此处获得
Example usage: 用法示例:
// 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];
});
}
For a start, a couple of MBs is not huge. 首先,几个MB并不庞大。 Doing it the same way for a couple of MBs would be absolutely fine.
以相同的方式对几个MB执行此操作绝对没问题。 But if you do want to write to the file as you receive the data then you could use an
NSFileHandle
. 但是,如果您确实想在接收数据时写入文件,则可以使用
NSFileHandle
。 Create one and then write data to it and then call synchronizeFile
on it when you want to flush the data to disk. 创建一个,然后向其中写入数据,然后调用
synchronizeFile
就可以了,当你想将数据刷新到磁盘。 You could call synchronizeFile
after say every 10MB have been written or something (and obviously at the end as well). 你可以称之为
synchronizeFile
说的每10MB已经(在末尾,显然也一样)被写入后或东西。
So eg: 所以例如:
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filename];
...
[fileHandle writeData:dataComeInFromURLConnection];
...
[fileHandle synchronizeFile];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.