沙盒机制
数据持久化的本质就是把数据有内存写入本地(也就是硬盘)在ios中值将数据写入到沙盒文件夹下
沙盒机制,就是指的是采取沙盒文件夹的形式管理应用程序的本地文件,而且沙盒文件夹的名字是随机分配的,采用十六进制方法命名
获取沙盒文件夹路径
NSHomeDirectory()
沙盒文件夹的主目录,在这个文件夹下存放着三个文件
Documents library tmp ,其中library中还存在连个文件
Cachers perference
,系统帮我们创建了五个文件存放在沙盒文件夹下,这个五个文件是不能删除的
NSLog(@"%@",NSHomeDirectory());
1.Documents 存储用户数据 需要备份的信息
Documents:存放一些比较重要的文件,文件大小比较小,这些文件都是可以有副本的,eg:数据库 此文件夹不能有太多东西,负责在上传到Appstroe中会直接拒掉
获取documents文件夹路径 第一个参数:文件夹的名字 第二个参数:搜索域 ,有优先级:user --local -- network -- syste 第三个参数:相对路径或者是绝对路径 YES代表绝对路径 NO代表相对路径 此方法,最早是应用在mac端开发的,对应pc端可以有很多的用户,所有该方法的返回值是一个数组,但是现在这个方法应用在移动端(ios端)而移动端的用户只有一个,所有获取的路径也只有一个
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask , YES)lastObject];
2.Libary 资源库
library资源库,存放一些不太重要的文件相对比较大,且其中有两个子文件
NSString *libaryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)lastObject];
3.Cacher 存储缓存文件,程序专用的支持文件
caches存储一些缓存的文件,如网页缓存,视频缓存,图片缓存,应用中“清除缓存”功能清理就是这个文件夹里面的内容
NSString *CachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
4.preferences 存储应用程序的偏好设置文件
preferences偏好设置,存放一些用户的信息 ####注意:路径是找不到的,只能通过NSUserDefault(是个单例类)访问
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
preferences中存放都是plist文件,在设置键值对的时候,第一次文件会帮你创建plist文件,如果直接取值的plist文件是没有的
[user setBool:YES forKey:@"login"];
BOOL isLogin = [user boolForKey:@"login"];
NSLog(@"%d",isLogin);
[user setBool:YES forKey:@"login"];
BOOL isLogin = [user boolForKey:@"login"];
NSLog(@"%d",isLogin);
NSUserDefaults
支持数据类型
array dictionary string data number BOOL integer
等
NSUserDefaults中一般存放数据类型数据,不存放大型的数据
5.Tmp 存储临时文件,比如:下载的zip包,解压后再删除
NSTemporaryDirectory();获取tmp的路径
NSLog(@"===============%@",NSTemporaryDirectory());
NSLog(@"===============%@",NSTemporaryDirectory());
NSFileManager(也是个单例类) 文件管理类,是一个文件管理工具,管理于文件的添加,删除,修改,拷贝,继承自NSobject
6. 获取沙盒目录路径的方法
NSHomeDirectory
—————>沙盒主路径
NSDocumentDirectory--------
>Documents文件夹
NSLibraryDirectory
——————
>Library文件夹
NSCachesDirectory
——————
>Caches文件夹
NSTemporaryDirectory()
—————
>tmp文件夹
(1) 在doucuments文件夹创建一个文件av.txt
1. 获取doucuments路径
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
// 2. 创建av.txt路径
// stringByAppendingFormat拼接上什么就得到什么
// stringByAppendingString拼上什么就得到什么
// stringByAppendingPathExtension拼接的嫩容前加一个点
// stringByAppendingPathComponent拼接的内容枪加一个反斜杠/
NSString *avPath = [documentPath stringByAppendingPathComponent:@"AV"];
NSLog(@"%@",avPath);
// 首先判断文件是否存在
if ([fileManger fileExistsAtPath:avPath]) {
NSLog(@"存在");
}else{
NSLog(@"不存在");
// 创建av.tex文件
// 第二参数:withIntermediateDirectories如果路径中没有文件夹,是否自动创建
BOOL isSuccss = [fileManger createDirectoryAtPath:avPath withIntermediateDirectories:YES attributes:nil error:nil];
if (isSuccss) {
NSLog(@"创建成功");
}else{
NSLog(@"创建失败");
}
}
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
// 2. 创建av.txt路径
// stringByAppendingFormat拼接上什么就得到什么
// stringByAppendingString拼上什么就得到什么
// stringByAppendingPathExtension拼接的嫩容前加一个点
// stringByAppendingPathComponent拼接的内容枪加一个反斜杠/
NSString *avPath = [documentPath stringByAppendingPathComponent:@"AV"];
NSLog(@"%@",avPath);
// 首先判断文件是否存在
if ([fileManger fileExistsAtPath:avPath]) {
NSLog(@"存在");
}else{
NSLog(@"不存在");
// 创建av.tex文件
// 第二参数:withIntermediateDirectories如果路径中没有文件夹,是否自动创建
BOOL isSuccss = [fileManger createDirectoryAtPath:avPath withIntermediateDirectories:YES attributes:nil error:nil];
if (isSuccss) {
NSLog(@"创建成功");
}else{
NSLog(@"创建失败");
}
}
7.删除文件夹
先判断有没有要删除的文件夹存在
if ([fileManger fileExistsAtPath:avPath]) {//如果存在就删除
BOOL isSuccss = [fileManger removeItemAtPath:avPath error:nil];
BOOL isSuccss = [fileManger removeItemAtPath:avPath error:nil];
NSLog(@"%@",isSuccss?@"删除成功":@"删除失败");
}
8.拷贝文件
拷贝文件
//把nv.plist 拷贝到av的文件夹下
// NSBundle应用程序包,我们从Appstroe下载到应用就是这个包
//把nv.plist 拷贝到av的文件夹下
// NSBundle应用程序包,我们从Appstroe下载到应用就是这个包
//获取应用程序包得路径 ios8.0之后,**.App单独存放一个文件内,只能读,不能写入,最终上传到Appstroe的包就是这个包
NSString *bundlePath = [[NSBundle mainBundle]bundlePath];
NSLog(@"%@",bundlePath);
1.获取NB.plist的路径
NSString *nbPath = [[NSBundle mainBundle]pathForResource:@"NB.plist" ofType:nil];
// 2.制造移动到沙盒documents文件下AV文件夹下NB.plist路径
NSString *desPath = [avPath stringByAppendingPathComponent:@"NB.plist"];
// 3.文件拷贝 第一个参数:拷贝之前的路径 第二个参数:要拷贝到的位置
if (![fileManger fileExistsAtPath:desPath]) {
BOOL isSucee = [fileManger copyItemAtPath:nbPath toPath:desPath error:nil];
NSLog(@"%@",isSucee? @"拷贝成功":@"拷贝失败");
}
NSString *nbPath = [[NSBundle mainBundle]pathForResource:@"NB.plist" ofType:nil];
// 2.制造移动到沙盒documents文件下AV文件夹下NB.plist路径
NSString *desPath = [avPath stringByAppendingPathComponent:@"NB.plist"];
// 3.文件拷贝 第一个参数:拷贝之前的路径 第二个参数:要拷贝到的位置
if (![fileManger fileExistsAtPath:desPath]) {
BOOL isSucee = [fileManger copyItemAtPath:nbPath toPath:desPath error:nil];
NSLog(@"%@",isSucee? @"拷贝成功":@"拷贝失败");
}
9.文件的移动 从AV文件下移动到library文件夹下
1.移动之前的路径
NSString *surcePath = desPath;
// 2.移动之后的路径
NSString *libaryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)lastObject];
NSString *toPath = [libaryPath stringByAppendingPathComponent:@"NB.plist"];
// 3.移动
if (![fileManger fileExistsAtPath:toPath]) {
BOOL isSuecc = [fileManger moveItemAtPath:surcePath toPath:toPath error:nil];
NSLog(@"%@",isSuecc?@"移动成功":@"移动失败");
}
NSString *surcePath = desPath;
// 2.移动之后的路径
NSString *libaryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)lastObject];
NSString *toPath = [libaryPath stringByAppendingPathComponent:@"NB.plist"];
// 3.移动
if (![fileManger fileExistsAtPath:toPath]) {
BOOL isSuecc = [fileManger moveItemAtPath:surcePath toPath:toPath error:nil];
NSLog(@"%@",isSuecc?@"移动成功":@"移动失败");
}
[self simpleObjectWriteFileAndReadFromFile];
简单对象写入文件
简单对象就是:NSString NSArray NSDictionary NSData以及他们的子类 NSArray NSDictionary必须是上面的四种基本数据类型,才能直接进行文件的写入和读取
1.字符串的写入
1.字符串的写入
NSString *string = @"我们从不生产代码,我们只是代码的搬运工";
// 2.在documents文件夹下创建一个文件“text.txt”
NSString *textPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"text.txt"];
// NSLog(@"%@",textPath);
// 3.字符串的写入 第一个参数:要写入的文件路径 第二参数:原子性,YES提供多线程的安全保护,NO则不提供安全保护,第三个参数:编码的格式
BOOL isSuccess = [string writeToFile:textPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSString *string = @"我们从不生产代码,我们只是代码的搬运工";
// 2.在documents文件夹下创建一个文件“text.txt”
NSString *textPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"text.txt"];
// NSLog(@"%@",textPath);
// 3.字符串的写入 第一个参数:要写入的文件路径 第二参数:原子性,YES提供多线程的安全保护,NO则不提供安全保护,第三个参数:编码的格式
BOOL isSuccess = [string writeToFile:textPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@",isSuccess?@"写入成功":@"写入失败");
4.字符串的从文件中读取数据 第一个参数:要读取的文件路径 第二个参数:编码格式
NSString *contentString = [NSString stringWithContentsOfFile:textPath encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@",contentString);
NSString *contentString = [NSString stringWithContentsOfFile:textPath encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@",contentString);
2.数组的读取和写入
1.
NSArray *array = @[@"索宁",@"尹君",@"余姚",@"土传"];
// 2.将数组写入到cacher文件下的array.text
// 3.数组的写入后的文件是XML格式
NSString *arrayPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"array.text"];
isSuccess = [array writeToFile:arrayPath atomically:YES];
NSLog(@"%@",isSuccess?@"数组写入成功":@"数组写入失败");
// 4.数组的读取
NSArray *contentArray = [NSArray arrayWithContentsOfFile:arrayPath];
NSLog(@"%@",contentArray);
NSArray *array = @[@"索宁",@"尹君",@"余姚",@"土传"];
// 2.将数组写入到cacher文件下的array.text
// 3.数组的写入后的文件是XML格式
NSString *arrayPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"array.text"];
isSuccess = [array writeToFile:arrayPath atomically:YES];
NSLog(@"%@",isSuccess?@"数组写入成功":@"数组写入失败");
// 4.数组的读取
NSArray *contentArray = [NSArray arrayWithContentsOfFile:arrayPath];
NSLog(@"%@",contentArray);
3.字典的写入和读取
1.字典的写入和读取
NSDictionary *dictionary = @{@"妖":@"索宁",@"尹君":@"夏银军",@"坑":@"余姚",@"闷骚":@"土川"};
2. tmp夹下创建一个dictionary.text
NSString *dictionaryPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"dictionary.txt"];
isSuccess = [dictionary writeToFile:dictionaryPath atomically:YES];
NSLog(@"55555555555%@",isSuccess?@"字典写入成功":@"字典希尔失败");
NSDictionary *dictionary = @{@"妖":@"索宁",@"尹君":@"夏银军",@"坑":@"余姚",@"闷骚":@"土川"};
2. tmp夹下创建一个dictionary.text
NSString *dictionaryPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"dictionary.txt"];
isSuccess = [dictionary writeToFile:dictionaryPath atomically:YES];
NSLog(@"55555555555%@",isSuccess?@"字典写入成功":@"字典希尔失败");
4.二进流的写入和读取
NSData写入和读取 写入后变成XML格式
NSString *dataString = @"你该洗脚了";
// 准备NSdata对象
NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
// 1.在liblary写入data.txt
//
NSString *dataPath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:dataString];
isSuccess = [data writeToFile:dataPath atomically:YES];
NSLog(@"%@",isSuccess?@"二进制写入成功":@"二进制写入失败");
NSData *contentData= [NSData dataWithContentsOfFile:dataPath];
// 二进制转换为字符串
NSString *newString = [[[NSString alloc]initWithData:contentData encoding:NSUTF8StringEncoding]autorelease];
NSLog(@"%@",newString);
NSString *dataString = @"你该洗脚了";
// 准备NSdata对象
NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
// 1.在liblary写入data.txt
//
NSString *dataPath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:dataString];
isSuccess = [data writeToFile:dataPath atomically:YES];
NSLog(@"%@",isSuccess?@"二进制写入成功":@"二进制写入失败");
NSData *contentData= [NSData dataWithContentsOfFile:dataPath];
// 二进制转换为字符串
NSString *newString = [[[NSString alloc]initWithData:contentData encoding:NSUTF8StringEncoding]autorelease];
NSLog(@"%@",newString);
归档 和 反归档
复杂对象就是
Foundation
框架下不存在的数据类,也就是我们自定义类,就叫复杂对象,复杂对象是不能直接希尔到文件中,必须借助一些工具,
NSKeyArchiver
(归档工具)读取的时必须借助工具类
NSKeyUnarchiver
(反归档工具)
Person *p1 = [[[Person alloc]initWithName:@"威哥" gender:@"男" age:18]autorelease];
NSMutableData *data = [NSMutableData data];
// 1. 创建归档对象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
// 2. 归档 的哥参数:要被归档的对象 第二个参数:给归档对象一个key值作为标示,方便反归档时候把他找回来
[archiver encodeObject:p1 forKey:@"boyFriend"];
// 3.完成归档
[archiver finishEncoding];
[archiver release];
将归档后的数据写入文件
// 将文件写入沙盒文件下
NSString *personPath = [NSHomeDirectory() stringByAppendingPathComponent:@"person.txt"];
BOOL isSuccess =[data writeToFile:personPath atomically:YES];//将转换后的data数据写入到文件中
NSLog(@"======================%@",isSuccess?@"写入成功":@"写入失败");
NSData *contentData = [NSData dataWithContentsOfFile:personPath];
// 创建反归档工具
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:contentData];
// 2.通过可以值找到Person对象
Person *p2 = [unarchiver decodeObjectForKey:@"boyFriend"];
NSLog(@"==========================%@",p2);
[unarchiver finishDecoding];//停止返归当
[unarchiver release];
// 将文件写入沙盒文件下
NSString *personPath = [NSHomeDirectory() stringByAppendingPathComponent:@"person.txt"];
BOOL isSuccess =[data writeToFile:personPath atomically:YES];//将转换后的data数据写入到文件中
NSLog(@"======================%@",isSuccess?@"写入成功":@"写入失败");
NSData *contentData = [NSData dataWithContentsOfFile:personPath];
// 创建反归档工具
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:contentData];
// 2.通过可以值找到Person对象
Person *p2 = [unarchiver decodeObjectForKey:@"boyFriend"];
NSLog(@"==========================%@",p2);
[unarchiver finishDecoding];//停止返归当
[unarchiver release];
#pragma mark 数组和复杂对象结合 复杂对象存入数组要想完成归档,那么存入的复杂对象必须要遵从NScoding协议
Person *p3 = [[Person alloc]initWithName:@"索宁" gender:@"人妖" age:18];
Person *p4 = [[Person alloc]initWithName:@"尹君" gender:@"男" age:20];
NSArray *pArray = @[p3,p4];
[p3 release];
[p4 release];
// 使用归档将数组写入到文件
// 1.创建归档工具
NSMutableData *mdata = [NSMutableData data];
NSKeyedArchiver *nArchiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:mdata];
// 使用归档对象把数组归档
[nArchiver encodeObject:pArray forKey:@"array"];
// 3.停止归档工具
[nArchiver finishEncoding];
// 4.释放
[nArchiver release];
[p3 release];
[p4 release];
// 使用归档将数组写入到文件
// 1.创建归档工具
NSMutableData *mdata = [NSMutableData data];
NSKeyedArchiver *nArchiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:mdata];
// 使用归档对象把数组归档
[nArchiver encodeObject:pArray forKey:@"array"];
// 3.停止归档工具
[nArchiver finishEncoding];
// 4.释放
[nArchiver release];
文件写入到document文件夹下array.txt
NSString *documentPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"array.txt"];
isSuccess = [mdata writeToFile:documentPath atomically:YES];
NSLog(@"------------------%@",isSuccess?@"复杂数组写入成功":@"复杂数组写入失败");
// 复杂数组读取
NSData *nData = [NSData dataWithContentsOfFile:documentPath];
// 创建返归当数据
NSKeyedUnarchiver *nUnarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:nData];
///通过key值将对象反归档
NSArray *contrenAray = [nUnarchiver decodeObjectForKey:@"array"];
// 停止反归档数据
[nUnarchiver finishDecoding];
// 释放
[nUnarchiver release];
NSLog(@"##############%@ %@",contrenAray[0],contrenAray[1]);
NSString *documentPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"array.txt"];
isSuccess = [mdata writeToFile:documentPath atomically:YES];
NSLog(@"------------------%@",isSuccess?@"复杂数组写入成功":@"复杂数组写入失败");
// 复杂数组读取
NSData *nData = [NSData dataWithContentsOfFile:documentPath];
// 创建返归当数据
NSKeyedUnarchiver *nUnarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:nData];
///通过key值将对象反归档
NSArray *contrenAray = [nUnarchiver decodeObjectForKey:@"array"];
// 停止反归档数据
[nUnarchiver finishDecoding];
// 释放
[nUnarchiver release];
NSLog(@"##############%@ %@",contrenAray[0],contrenAray[1]);
代理方法
//归档的协议方法 它的属性也要归档,此时要对它的属性进行编码
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.gender forKey:@"gender"];
[aCoder encodeInteger:self.age forKey:@"age"];
// [aCoder encodeObject:@(self.age) forKey:@"age"];//这样写也可以
}
//反归档协议方法
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.gender = [aDecoder decodeObjectForKey:@"gender"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
// self.age = [[aDecoder decodeObjectForKey:@"age"]integerValue];//这样写也可以
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.gender forKey:@"gender"];
[aCoder encodeInteger:self.age forKey:@"age"];
// [aCoder encodeObject:@(self.age) forKey:@"age"];//这样写也可以
}
//反归档协议方法
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.gender = [aDecoder decodeObjectForKey:@"gender"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
// self.age = [[aDecoder decodeObjectForKey:@"age"]integerValue];//这样写也可以
}
return self;
}