沙盒机制
1.每一个APP安装到手机上或者模拟器上都会自动生成3个文件夹,这3个文件夹可以理解为这个APP的沙盒
2.并且每个APP的文件夹都是相对独立的 只能自己的应用去访问,不可以互相访问
3.并且文件夹中存储的是代码以外的所有数据,例如(图片、素材、声音、视频、文档等)也就是说,持久化文件(缓存文件)可以存储到文件夹中
打印沙盒的各个文件夹路径
// 打印沙盒的各个文件夹路径 - (void)path { /* 每一次运行时都是重新安装的过程,都会随机生成一个新的沙盒路径(名字是随机的) 注意:要获取的是当前的沙盒路径 */ // 打印沙盒主路径 NSString *path = NSHomeDirectory(); NSLog(@"%@",path); // Documents文件夹 // 可以被iTunes备份 可以保存一些用户的数据 及缓存文件等 // NSDocumentDirectory 要获取的文件夹路径 // NSUserDomainMask 搜索的范围 // YES 是否获取全路径 NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentPath = [documents lastObject]; NSLog(@"%@", documentPath); // 获取Library文件夹路径 // Library可以被iTunes备份 // Caches 主要存储系统缓存文件 // Preferences 系统配置文件 NSArray *library = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); NSString *libPath = [library lastObject]; NSLog(@"%@", libPath); // 获取 temp 文件夹 // 主要存储 临时文件 // 当手机重新启动时 该文件夹得文件 会被删除 // (有可能不重启 也被删除) NSString *tempPath = NSTemporaryDirectory(); NSLog(@"%@", tempPath); }
简单对象的写入
系统的类实力出来的对象 叫简单对象
例如:字符串 数组 字典 二进制对象(NSData)
如果要写入一个数组或字典等容器类对象
那么这个容器当中也要保存是 简单对象才能写入- (void)write { // 把字符串 存储到沙盒当中 NSString *str = @"第一章 盘古开天"; // 拼接文件存储的路径 NSString *strPath = [kDocumentPath :@"/xiaoshuo.txt"]; NSLog(@"%@", strPath); // 进行简单对象的写入 // atomically 保护写入作用 // 在写入过程中 出现意外情况 额可以写入成功 NSError *error = nil; [str writeToFile:strPath atomically:YES encoding:NSUTF8StringEncoding error:&error]; NSLog(@"%@", strPath); // 写入一个数组 NSArray *array = @[@"旭阳",@"赵姐",@"张文",@"壮壮"]; NSString *arrayPath = [kDocumentPath stringByAppendingString:@"/Array.plist"]; [array writeToFile:arrayPath atomically:YES]; NSDictionary *dic = @{@"name":@"dj",@"age":@"22"}; NSString *dicPath = [kDocumentPath stringByAppendingString:@"/dic.plist"]; [dic writeToFile:dicPath atomically:YES]; // 写入data NSString *dataStr = @"哈哈哈"; NSData *data = [dataStr dataUsingEncoding:NSUTF8StringEncoding]; NSString *dataPath = [kDocumentPath stringByAppendingString:@"/data"]; [data writeToFile:dataPath atomically:YES]; // data文件一般是存储图片的 // UIImagePNGRepresentation 把图片转化成data类型 NSData *imageData = UIImagePNGRepresentation([UIImage imageNamed:@"9"]); // 拼接路径 NSString *imagePath = [kDocumentPath stringByAppendingString:@"/image"]; [imageData writeToFile:imagePath atomically:YES]; }
- 读取数据
- (void)readData { // 读取(按路径进行读取) NSString *arrayPath = [kDocumentPath stringByAppendingString:@"/Array.plist"]; // 从该路径进行读取 NSArray *array = [NSArray arrayWithContentsOfFile:arrayPath]; NSLog(@"%@", array); // 读取data 图片 NSString *imagePath = [kDocumentPath stringByAppendingString:@"/image"]; NSData *imageData = [NSData dataWithContentsOfFile:imagePath]; // 把data转化为图片 UIImage *image = [UIImage imageWithData:imageData]; }
NSFileManager
管理文件的一个类,单例类。可以对文件进行创建、移动、复制、删除。
创建文件夹方法
- (void)createFile { // 获取要创建的路径 NSString *path = [kDocumentPath stringByAppendingPathComponent:@"/DownLoad"]; NSLog(@"%@", path); // 创建文件管理器 NSFileManager *manager = [NSFileManager defaultManager]; // 创建文件夹 // withIntermediateDirectories 是否覆盖之前的文件,如果填No,就是不覆盖 // 不覆盖就相当于创建文件夹失败 BOOL isCreate = [manager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil]; // 打印是否创建成功 NSLog(@"%d", isCreate); }
移动文件夹
- (void)moveFile { // 获取原路径 NSString *oldPath = [kDocumentPath stringByAppendingPathComponent:@"/DownLoad"]; // 获取新路径 NSString *newPath = [kCachesPath stringByAppendingPathComponent:@"/DownLoad"]; // 创建文件管理对象 NSFileManager *manager = [NSFileManager defaultManager]; // 移动文件夹(从老的移动到新的路径) BOOL isMove = [manager moveItemAtPath:oldPath toPath:newPath error:nil]; NSLog(@"%d", isMove); }
拷贝文件夹
- (void)copyFile { // 原路径 NSString *oldPath = [kDocumentPath stringByAppendingString:@"/DownLoad"]; // 要拷贝的路径 NSString *newPath = [kCachesPath stringByAppendingString:@"/DownLoad"]; NSFileManager *manager = [NSFileManager defaultManager]; // 拷贝(原路径的文件夹 没有被删除 拷贝了一份到新路径) BOOL isCopy = [manager copyItemAtPath:oldPath toPath:newPath error:nil]; NSLog(@"%d", isCopy); }
删除文件夹
- (void)removeFile { // 获取要删除的路径 NSString *path = [kDocumentPath stringByAppendingPathComponent:@"/DownLoad"]; // 创建文件管理对象 NSFileManager *manager = [NSFileManager defaultManager]; BOOL isRemove = [manager removeItemAtPath:path error:nil]; NSLog(@"%d", isRemove); }
判断文件夹是否存在
- (void)isExecute { NSString *path = [kCachesPath stringByAppendingPathComponent:@"/DownLoad"]; // 创建文件管理对象 NSFileManager *manager = [NSFileManager defaultManager]; BOOL isExecute = [manager isExecutableFileAtPath:path]; NSLog(@"%d", isExecute); }
复杂对象写入文件
复杂对象写入步骤:
1.遵守 NSCoding(需要在写入的时候,按照一定的规则进行写入,一定的编码格式去写入) 归档 与 反归档(序列与反序列)
2.重写(协议中)归档与反归档方法
3.创建一个复杂对象出来
4.创建归档对象
5.利用归档对象,把复杂对象 转化成data
6.把data写入文件 进行数据持久化
自己创建出来的类(例如 Student类)
Student.m:
// 归档方法 - (void)encodeWithCoder:(NSCoder *)aCoder { // 按照一定的编码格式归档 // 注意归档时候的key 要与 反归档时的key一致 [aCoder encodeObject:self.name forKey:@"name"]; // 要选用与属性类型一致的编码方法 [aCoder encodeInteger:self.age forKey:@"age"]; // 一般 统一使用对象类型 [aCoder encodeObject:self.imageData forKey:@"imageData"]; } // 反归档方法 - (id)initWithCoder:(NSCoder *)aDecoder { self = [super init]; if (self) { // 按照一定的编码格式 和存储的key编码标识 取出被归档的对象(反归档) self.name = [aDecoder decodeObjectForKey:@"name"]; self.age = [aDecoder decodeIntegerForKey:@"age"]; self.imageData = [aDecoder decodeObjectForKey:@"imageData"]; } return self; }
写入的核心思想:
把复杂对象转化成简单对象,进行写入。一般转化成NSData对象进行写入。- (void)viewDidLoad { [super viewDidLoad]; // 复杂对象写入文件 // 自己创建出来的类(例如 Student类) // 写入的核心思想: // 把复杂对象转化成简单对象,进行写入 // 一般转化成NSData对象进行写入 Student *stu = [[Student alloc]init]; stu.name = @"aa"; stu.age = 22; stu.imageData = UIImagePNGRepresentation([UIImage imageNamed:@"9"]); // 创建一个可变data NSMutableData *data = [NSMutableData data]; // 创建一个归档对象 NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data]; // 将复杂对象通过归档对象转成data [archiver encodeObject:stu forKey:@"student"]; // 完成归档 [archiver finishEncoding]; // 实际上 通过归档对象把复杂对象写入data中 // 并且写入放入标识 就是key // 归档与反归档不是数据持久化,只是把复杂对象 按照系统的编码格式 转化成data // 真正的数据持久化 还是 写入文件 // 写入文件 // 获取路径 NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSLog(@"%@", path); //拼接路径 NSString *stuPath = [path stringByAppendingPathComponent:@"/student"]; // 写入文件 [data writeToFile:stuPath atomically:YES]; // 释放归档对象 [archiver release]; // 反归档 // 从沙盒中读取data数据 NSData *dataNew = [NSData dataWithContentsOfFile:stuPath]; // 创建反归档对象(利用data创建) NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:dataNew]; // 利用反归档对象 反归档出复杂对象 Student *stuNew = [unarchiver decodeObjectForKey:@"student"]; [unarchiver finishDecoding]; // UIImage *image = [UIImage imageWithData:stuNew.imageData]; [unarchiver release]; // 如何把一个数组的复杂对象 写到文件中 // 遍历数组,把每一个复杂对象转化成简单对象(data) // 再将data 保存到一个数组中 // 最后 直接把数组写入到文件进行初始化 }