热门搜索 :
考研考公
您的当前位置:首页正文

利用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任务队列我们可以很容易实现高效率的并发读取,而不需要关心线程锁。
Top