需求思路
- 读取时候可以并发进行,读取后要返回读取状态。
- 写入文件时候不可以读取,并且文件写入时不可以并发的进行写入操作。
代码思路
- 获取任务任务队列,读写操作都放进队列中进行,这样之后的操作可以针对任务队列进行。
- 文件管理类是单列,保证操作文件的队列只有一个。
- 写入操作前面的操作都需要完成,后面的操作要等待写入操作完成再继续,所以写入操作可以用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任务队列我们可以很容易实现高效率的并发读取,而不需要关心线程锁。