简体   繁体   English

将来自Web服务的大量数据分块写入文件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM