【iOS】线程安全的文件读写
前段时间看了一遍GCD(Grand Central Dispatch)多线程,GCD是苹果为多核开发提供的解决方案
多线程最常见的问题就是读写,比如数据库读写,文件读写,读取是共享的,写是互斥,允许多个线程进行读操作,当写文件时,阻止队列中所有其他的线程进入,直到文件写完成
本文利用GCD提供的相关API封装(主要有dispatch_barrier_async,dispatch_async,dispatch_queue_create)一个线程安全的文件读写类FileManager
注:这里使用的文件读写使用NSFileManager类,在测试过程发现多个线程同时写文件的时候并没有发现异常和报错,经过一番查阅发现,原来NSFileManager本身就是线程安全的,多个线程对文件进行写操作,并不会报异常
下面代码只作为加深GCD的学习,实际开发如果使用NSFileManager并不需要考虑线程安全问题(使用NSFileManager的delegate的时候需要注意,需要自己定义一个实例维护状态,避免与共享实例冲突)

SGFileManager.h
@interface SGFileManager : NSObject + (instancetype)shareInstance; - (NSData *)readFile:(NSString *)path;
- (void)readFileAsync:(NSString *)path complete:(void (^)(NSData *data))complete; - (BOOL)writeFile:(NSString *)path data:(NSData *)data;
- (void)writeFileAsync:(NSString *)path data:(NSData *)data complete:(void (^)(BOOL result))complete; @end
SGFileManager.m
#import "SGFileManager.h" //线程队列名称
static char *queueName = "fileManagerQueue"; @interface SGFileManager ()
{
//读写队列
dispatch_queue_t _queue;
} @end @implementation SGFileManager + (instancetype)shareInstance
{
static id instance = nil; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
}); return instance;
} - (instancetype)init
{
if(self = [super init]) {
_queue = dispatch_queue_create(queueName, DISPATCH_QUEUE_CONCURRENT);
}
return self;
} - (NSData *)readFile:(NSString *)path
{
__block NSData *data;
dispatch_sync(_queue, ^{
if([[NSFileManager defaultManager] fileExistsAtPath:path]){
data = [[NSFileManager defaultManager] contentsAtPath:path];
}
});
return data;
} - (void)readFileAsync:(NSString *)path complete:(void (^)(NSData *data))complete
{
dispatch_async(_queue, ^{
NSData *data = nil; if([[NSFileManager defaultManager] fileExistsAtPath:path]){
data = [[NSFileManager defaultManager] contentsAtPath:path];
} if (complete) {
complete(data);
}
});
} - (BOOL)writeFile:(NSString *)path data:(NSData *)data
{
__block BOOL result = NO;
dispatch_barrier_sync(_queue, ^{
NSFileManager *fileManager = [NSFileManager defaultManager];
if([fileManager fileExistsAtPath:path]){
[fileManager removeItemAtPath:path error:nil];
} result = [[NSFileManager defaultManager] createFileAtPath:path contents:data attributes:nil]; NSLog(@"写文件:");
});
return result;
} - (void)writeFileAsync:(NSString *)path data:(NSData *)data complete:(void (^)(BOOL result))complete
{
__block BOOL result = NO;
dispatch_barrier_async(_queue, ^{
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);
}
}); } @end
使用:
NSString *documentRoot = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [documentRoot stringByAppendingPathComponent:@"test.txt"]; [[SGFileManager shareInstance] writeFileAsync:filePath data:data complete:^(BOOL result) {
if (result) {
NSLog(@"异步写入文件成功");
}
}]; [[SGFileManager shareInstance] readFileAsync:filePath complete:^(NSData *data) {
if (data) {
NSLog(@"异步读取文件成功");
}
}];
使用GCD进行多线程开发还是挺方便的,不需要考虑锁的问题,并且性能也比较高,在开发中可以尽量使用GCD进行多线程的开发,并且GCD对从后台到UI的调用也非常方便
【iOS】线程安全的文件读写的更多相关文章
- ios 简单的plist文件读写操作(Document和NSUserDefaults)
最近遇到ios上文件读写操作的有关知识,记录下来,以便以后查阅,同时分享与大家. 一,简单介绍一下常用的plist文件. 全名是:Property List,属性列表文件,它是一种用来存储串行化后的对 ...
- iOS数据持久化文件读写之偏好设置
很多iOS应用都支持偏好设置,比如保存用户名.密码.字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能.每个应用都有个NSUserDefaults实例,通过它来存取偏好设置.比如, ...
- Cocos2d-x在win32,android和IOS下的文件读写问题
最近在学习和使用Cocos2d-x框架,虽然说的是跨平台,但是在用VS进行开发,然后移植到android或IOS下,也可能会出现各种问题,需要做细微的调整. 例如我在做文件读写操作的时候,很可能在wi ...
- ios本地文件内容读取,.json .plist 文件读写
ios本地文件内容读取,.json .plist 文件读写 本地文件.json .plist文件是较为常用的存储本地数据的文件,对这些文件的操作也是一种常用的基础. 本文同时提供初始化变量的比较标准的 ...
- iOS面向编码|iOSVideoToolbox:读写解码回调函数CVImageBufferRef的YUV图像
iOS面向编码|iOSVideoToolbox:读写解码回调函数CVImageBufferRef的YUV图像 本文档基于H.264的解码,介绍读写Video Toolbox解码回调函数参数CVImag ...
- iOS 线程安全
线程安全: 当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题.就好比几个人在同一时修改同一个表格,造成数据的错乱. 解决多线程安全问题的方法 方法一:互斥锁(同步锁) @synchroni ...
- 实现iOS图片等资源文件的热更新化(三):动态的资源文件夹
简介 此文,将尝试动态从某个不确定的文件夹中加载资源文件.文章,会继续完善自定义的 imageNamed 函数,并为下一篇文章铺垫. 这么做的意义 正如我们经常所说的那样,大多数情景知道做事的意义往往 ...
- (转)linux文件读写的流程
转自http://hi.baidu.com/_kouu/item/4e9db87580328244ef1e53d0 在<linux内核虚拟文件系统浅析>这篇文章中,我们看到文件是如何被打开 ...
- C++文件读写详解(ofstream,ifstream,fstream)
C++文件读写详解(ofstream,ifstream,fstream) 这里主要是讨论fstream的内容: #include <fstream> ofstream //文件写操作 内存 ...
随机推荐
- node中使用domain处理异步异常问题
domain实际上是一个隔离容器,将一个或者多个eventEmiter放入容器中,这样由该event发出的事件,如果出现异常就会最终被该domain捕获. demo代码可参见: var EventEm ...
- 解决cxf+spring发布的webservice,types,portType和message以import方式导入
用cxf+spring发布了webservice,发现生成的wsdl的types,message和portType都以import的方式导入的.. 原因:命名空间问题 我想要生成的wsdl在同个文件中 ...
- 【网络编程】——connect函数遇见EINTR的处理
最近在公司项目中突然报错如下 “connect: Interrupted system call”, 经过查找代码发现是在创建 socket 中执行了 connect 函数失败导致.上网查阅资料发现这 ...
- Centos 6.5 下安装socket5代理
---恢复内容开始--- 1. 安装 先安装依赖库 yum -y install gcc gcc-c++ automake make pam-devel openldap-devel cyrus-sa ...
- Xcode 6 UITextField 键盘不弹出
iOS Simulator -> Hardware -> Keyboard Uncheck "Connect Hardware Keyboard"
- 计算A/3,不用除法
int DividedBy3(int A) { ; ; i <= ; i += ) p += A << i; return (-p); }
- pentaho saiku 安装全过程
公司希望也开发一套多维分析系统,以解决运营/产品无休止的需求和技术人力不足的矛盾! 一.开发选型: 一.BIRT:易用性差,所以没再使用 二.JasperReport+ireport:文档收费,不支持 ...
- 用 Wireshark 图解:TCP 三次握手
摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “snow warn throughout the winter” 一.什么是 Wireshar ...
- 图解 Java IO : 二、FilenameFilter源码
Writer :BYSocket(泥沙砖瓦浆木匠) 微 博:BYSocket 豆 瓣:BYSocket FaceBook:BYSocket Twitter ...
- 萝卜叶万能助手SEO网络营销简介
萝卜叶万能助手专业版是就是将我们10年的SEO经验和方法汇聚于一体的结晶,旨在打造一款使用简单方便,功能强大的SEO软件,以便节省您的时间,提高您收集资料.维护网站.发布帖子.进行网络营销的效率. 借 ...