IOS文件系统
1.IOS文件系统遵循一个沙盒机制,IOS中的沙盒机制(SandBox)是一种安全体系,它规定了应用程序只能在为该应用创建的文件夹内读取文件,不可以访问其他地方的内容。所有的非代码文件都保存在这个地方,比如图片、声音、属性列表和文本文件等。
1>每个应用程序都在自己的沙盒内
2>不能随意跨越自己的沙盒去访问别的应用程序沙盒的内容
3>应用程序向外请求或接收数据都需要经过权限认证
2.当一个APP被安装在IOS系统,系统就会为其创建一个遵循沙盒机制的文件系统,该文件系统有三个文件:
1>Documents:用户在使用APP过程产生数据都会保存在此文件夹下,如果APP使用了ICloud技术,此文件夹的数据将会进行云同步
2>Library:用户偏好设置及缓存设置,通常和NSUserDefualt类来访问此文件路径
3>tmp
3.系统提供两个类来操作APP的文件系统
NSFileManager NSFileHandle
沙盒路径目录结构
Documents:应用程序将其数据存储在Documents目录中,例如从网路下载的图片或者应用程序产生的文档内容等
目录路径的获取:
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSLog(@"%@", path);
注:第一个参数为查找的是Documents目录,第二个参数指定的是讲搜索限制在应用程序沙盒内,第三个参数如果为yes会将检索后的路径中~符号展开为实际路径,由于检索处的paths为一个数组,但是里面只有一个路径,所以用firstObject来获取唯一的Documents路径。
Library:用户首选项设置都存储在Library/Preferences文件夹中。该文件夹一般不作为应用程序产生文档的存储位置。
目录路径的获取:
NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
NSLog(@"%@", path);
tmp:该目录提供应用程序存储临时文件,应用程序中产生的文档页可以临时放入此目录,但是此目录在iTunes同步设备时不备份。
目录路径的获取:
NSString *path = NSTemporaryDirectory();
NSLog(@"%@", path);
数据持久化分大概分为以下5种
plist文件(属性列表)
preference(偏好设置)
NSKeyedArchiver(归档)
SQLite 3
CoreData
一、plist文件(属性列表)
plist文件是将某些特定的类,通过XML文件的方式保存在目录中。 用于存储键值对小数据是最合算的,因为其速率快!
//路径的获取
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [paths objectAtIndex:0];
NSString *myFile = [docPath stringByAppendingPathComponent:@"my.list”];
//写入文件 存储时使用writeToFile: atomically:方法。 其中atomically表示是否需要先写入一个辅助文件,再把辅助文件拷贝到目标文件地址。这是更安全的写入文件方法,一般都写YES。
NSArray *array = @[@"123", @"456", @"789"];
[array writeToFile:myFile atomically:YES];
//文件读取
NSArray *result = [[NSArray alloc] initWithContentsOfFile:myFile];
二、preference(偏好设置)
//1.获得NSUserDefaults文件
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//2.向文件中写入内容
[userDefaults setObject:@"AAA" forKey:@"a"];
[userDefaults setBool:YES forKey:@"sex"];
[userDefaults setInteger:21 forKey:@"age"];
//2.1立即同步
[userDefaults synchronize];
//3.读取文件
NSString *name = [userDefaults objectForKey:@"a"];
BOOL sex = [userDefaults boolForKey:@"sex"];
NSInteger age = [userDefaults integerForKey:@"age"];
NSLog(@"%@, %d, %ld", name, sex, age);
注:
1.偏好设置是专门用来保存应用程序的配置信息的,一般不要在偏好设置中保存其他数据。
2.如果没有调用synchronize方法,系统会根据I/O情况不定时刻地保存到文件中。所以如果需要立即写入文件的就必须调用synchronize方法。
3.偏好设置会将所有数据保存到同一个文件中。即preference目录下的一个以此应用包名来命名的plist文件。
三、NSKeyedArchiver(归档)
如果要归档的类型为标量或者是已经实现了NSCoding协议的,均不需要再进行特殊处理,可直接进行归档。如果是自定义类型,则必须要实现NSCoding协议才可以进行归档操作。
NSCoding协议声明了两个方法,这两个方法都是必须实现的。一个用来说明如何将对象编码到归档中,另一个说明如何进行解档来获取一个新对象(取消归档)。两个方法都传递一个NSCoder实例的参数。使用这个参数可以对这些自定义对象的各个成员进行编码和解码。如果自定义对象的成员中包含了另外的自定义对象,这个被包含的自定义对象也要实现NSCoding协议。
实现如下
新建一个类,并遵循NSCoding协议
//归档
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_desc forKey:@”desc”];
[aCoder encodeObject:_imageurls forKey:@”imageurls”];
[aCoder encodeObject:_source forKey:@”source”];
[aCoder encodeObject:_title forKey:@”title”];
[aCoder encodeObject:_link forKey:@”link”];
}
注:如果需要归档的类是某个自定义类的子类时,就需要在归档和解档之前先实现父类的归档和解档方法。即 [super encodeWithCoder:aCoder] 和 [super initWithCoder:aDecoder] 方法;
//解档
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
[aDecoder decodeObjectForKey:@”desc”];
[aDecoder decodeObjectForKey:@”imageurls”];
[aDecoder decodeObjectForKey:@”source”];
[aDecoder decodeObjectForKey:@”title”];
[aDecoder decodeObjectForKey:@”link”];
}
return self;
}
到需要值得视图控制器进行写入和读取
//读取归档文件
NSData *data = [[NSMutableDataalloc] initWithContentsOfFile:myFile];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiveralloc] initForReadingWithData:data];
TestObj * test = [unarchiver decodeObjectForKey:@”data”];
[unarchiver finishDecoding];
//写入归档文件
NSMutableData *data1 = [[NSMutableDataalloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiveralloc] initForWritingWithMutableData:data1];
[archiver encodeObject:test forKey:@”data”];
[archiver finishEncoding];
[data writeToFile:myFile atomically:YES];
四、文件的写入和读取
1.写入 //应用程序根目录的获取
NSString *homePath = NSHomeDirectory();
NSLog(@”%@”,homePath);
//Documents目录的获取
// NSString *documentPath = [homePath stringByAppendingPathComponent:@”documents”];
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//创建一个文件夹
NSFileManager *fileManager = [NSFileManager defaultManager];
//首先判断是否存在此文件夹
NSString *dirPath = [documentPath stringByAppendingPathComponent:@”diary”];
if(![fileManagerfileExistsAtPath:dirPath]) {[fileManagercreateDirectoryAtPath:dirPathwithIntermediateDirectories:YESattributes:nilerror:nil];
}
//将需要的数据保存到字典中
NSDictionary*dic =@{@”content”:self.textView.text,@”date”:[NSDatedate]};
//时间格式转换
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:@”yyyy年MM月dd日HH时mm分ss秒”];
NSString *string = [dateFormatter stringFromDate:[NSDate date]];
//将时间保存为文件名称后缀为txt
NSString *filePath = [dirPath stringByAppendingPathComponent:[NSString stringWithFormat:@”%@.txt”,string]];
//判断是否写入成功
if ([dic writeToFile:filePath atomically:YES]) {
self.textView.text = @”“;
}else{
NSLog(@”保存失败”);
}
2.读取
//读文件
//拿数据
NSString*documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)firstObject];
NSString *dirPath = [documentPath stringByAppendingPathComponent:@”diary”];
//将去到数据放到数组
dataSource = [NSMutableArray arrayWithArray:[[NSFileManager defaultManager] subpathsAtPath:dirPath]];
四、coredata的使用
在已有文件创建coredata时需要以下配置
在app delegate.m文件中添加
#pragma mark - Core Data stack
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (NSURL *)applicationDocumentsDirectory {
// The directory the application uses to store the Core Data store file. This code uses a directory named "com.Yujunliu.UI__coreData" in the application's documents directory.
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
- (NSManagedObjectModel *)managedObjectModel {
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"GifModel" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it.
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
// Create the coordinator and store
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"GifModel.sqlite"];
NSError *error = nil;
NSString *failureReason = @"There was an error creating or loading the application's saved data.";
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// Report any error we got.
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
dict[NSUnderlyingErrorKey] = error;
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
- (NSManagedObjectContext *)managedObjectContext {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
return nil;
}
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
}
#pragma mark - Core Data Saving support
- (void)saveContext {
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
NSError *error = nil;
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
在app delegate.h文件中添加
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
//插入数据
+(BOOL)insertGifModel:(NSDictionary*)gifmodelDic{
BOOL flag = NO;
//拿到context
AppDelegate *appdelegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = appdelegate.managedObjectContext;
GifModel *gifModel = [NSEntityDescription insertNewObjectForEntityForName:@"GifModel" inManagedObjectContext:context];
//进行赋值插入
gifModel.headpicture = gifmodelDic[@"headpicture"];
gifModel.nickname = gifmodelDic[@"nickname"];
gifModel.createtime = gifmodelDic[@"createtime"];
gifModel.text = gifmodelDic[@"text"];
gifModel.commentsno = gifmodelDic[@"commentsno"];
gifModel.gifurl = gifmodelDic[@"gifurl"];
gifModel.isZan = gifmodelDic[@"isZan"];
gifModel.newsid = gifmodelDic[@"newsid"];
gifMdel.userid = gifmodelDic[@"userid"];
//保存
[appdelegate saveContext];
NSError *error = nil;
if ([context save:&error]) {
NSLog(@"插入成功");
flag = YES;
}else{
NSLog(@"error = %@",error.debugDescription);
}
return flag;
}
//根据条件修改数据
+(BOOL)updataGifModel:(NSFetchRequest *)fetchRequst string:(NSString *)newContent{
BOOL flag = NO;
//拿到context
AppDelegate *appdelegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = appdelegate.managedObjectContext;
NSError *error = nil;
NSArray *datas = [context executeFetchRequest:fetchRequst error:&error];
if (!error && datas.count >0) {
for (int i = 0; i<datas.count; i++) {
//赋值新值
GifModel *gifModel = datas[i];
gifModel.text = newContent;
[appdelegate saveContext];
if ([context save:&error]) {
NSLog(@"修改成功");
flag = YES;
}else{
NSLog(@"修改失败");
flag = NO;
}
}
}
return flag;
}
//根据条件删除数据
+(BOOL)deleteGifModel:(NSFetchRequest *)fetchRequest{
BOOL flag = NO;
//拿到context
AppDelegate *appdelegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = appdelegate.managedObjectContext;
NSError *error = nil;
NSArray *datas = [context executeFetchRequest:fetchRequest error:&error];
if (!error && datas.count>0) {
for (int i =0; i<datas.count; i++) {
//删除满足条件的gifModel
[context deleteObject:datas[i]];
[appdelegate saveContext];
if ([context save:&error]) {
NSLog(@"删除成功");
flag = YES;
}else{
NSLog(@"error = %@",error.debugDescription);
flag = NO;
}
}
}
return flag;
}
//删除所有数据
+(BOOL)deleteAll{
BOOL flag = NO;
//拿到context
AppDelegate *appdelegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = appdelegate.managedObjectContext;
NSEntityDescription *description = [NSEntityDescription entityForName:@"GifModel" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setIncludesPropertyValues:NO];
[request setEntity:description];
flag = [GifModel deleteGifModel:request];
return flag;
}
//查找所有数据
+(NSMutableArray *)find{
NSMutableArray *array = [NSMutableArray array];
//拿到context
AppDelegate *appdelegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = appdelegate.managedObjectContext;
NSEntityDescription *description = [NSEntityDescription entityForName:@"GifModel" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setIncludesPropertyValues:NO];
[request setEntity:description];
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"newsid" ascending:NO];
request.sortDescriptors = @[sort];
NSError *error = nil;
NSArray *datas = [context executeFetchRequest:request error:&error];
if (!error) {
[array addObjectsFromArray:datas];
}
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSLog(@"%@",path);
return array;
}
//根据条件查询数据
+(NSMutableArray *)findWithFetchRequest:(NSFetchRequest *)request{
NSMutableArray *array = [NSMutableArray array];
//拿到context
AppDelegate *appdelegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = appdelegate.managedObjectContext;
NSError *error = nil;
NSArray *datas = [context executeFetchRequest:request error:&error];
if (!error) {
[array addObjectsFromArray:datas];
}
return array;
}
coredata的增删改查方法就这样定义完了,当需要进行数据库操作时,调用方法即可