利用GCD实现高效的文件读取

需求思路

  • 读取时候可以并发进行,读取后要返回读取状态。
  • 写入文件时候不可以读取,并且文件写入时不可以并发的进行写入操作。

代码思路

  • 获取任务任务队列,读写操作都放进队列中进行,这样之后的操作可以针对任务队列进行。
  • 文件管理类是单列,保证操作文件的队列只有一个。
  • 写入操作前面的操作都需要完成,后面的操作要等待写入操作完成再继续,所以写入操作可以用GCD 中的dispatch_barrier 函数进行操作拦截。
  • dispatch_barrier 此函数中的操作没有执行完不会执行队列里的其他操作

核心代码

//任务队列,文件读写单例类初始化时一同创建,用来管理读写任务,所有的读写操作都放到队列中,
@property (nonatomic,strong) dispatch_queue_t fileQueue;

self.syncQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//文件并发读取,读取后block 返回
- (void)readFileAsync:(NSString *)path complete:(void (^)(NSData *data))complete
{
    dispatch_async(_fileQueue, ^{
        
        NSData *filedata = nil;
        if([[NSFileManager defaultManager] fileExistsAtPath:path]){
            filedata = [[NSFileManager defaultManager] contentsAtPath:path];
        }
        
        if (complete) {
            complete(filedata);
        }
    });
}
// 异步写入文件,不影响主线程的其他操作
- (void)writeFileAsync:(NSString *)path data:(NSData *)data complete:(void (^)(BOOL result))complete
{
    __block BOOL result = NO;
    
    dispatch_barrier_async(_fileQueue, ^{
        //操作 ,写入文件
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if([fileManager fileExistsAtPath:path]){//
            [fileManager removeItemAtPath:path error:nil];
        }
        result = [[NSFileManager defaultManager] createFileAtPath:path contents:data attributes:nil];
        
        if (complete) {
            complete(result);
        }
    });
    
}
通过GCD任务队列我们可以很容易实现高效率的并发读取,而不需要关心线程锁。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容