沙盒机制:
1.每一个APP安装到手机上(或者模拟器上) 都会自动生成三个文件夹 这三个文件夹叫沙盒 可以理解为这个APP的沙盒
2.每个APP的文件夹都是相对独立的 只能自己的应用去访问 不可以互相访问
3.文件夹中 存储的是 代码以外的 所有数据 例如图片素材 声音 视频 文档等 也就是说 咱们的持久化文件 或者说缓存文件 可以存储到文件夹中
打印沙盒的各个文件夹路径:
- (void)path
{
/*
每一次运行的时候 都是重新安装的过程 都会随机生成一个新的沙盒路径(名字是随机的)
注意: 要获取的是当前的沙盒路径
*/
// 打印沙盒路径
NSString *appPath = NSHomeDirectory();
NSLog(@"%@",appPath);
// 获取Documents文件夹路径
// 此文件夹可以被iTunes备份 可以保存一些用户的数据 及 缓存文件等
// NSDocumentDirectory 要获取的文件夹路径
// NSUserDomainMask 搜索的范围
// YES 是否获得全路径
NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(@"%@",documents[0]);
// 获取library路径
// library文件夹可以被iTunes备份
// Caches 主要存储系统缓存文件
// Preferences 系统配置文件
NSArray *library = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSLog(@"%@",library[0]);
// 获取tmp路径
// 主要存储临时文件
// 当手机关机 或者说手机重新启动的时候 该文件夹的文件 会被删除
// 有可能 不关机 不重启 也被删除
NSString *tmp = NSTemporaryDirectory();
NSLog(@"%@",tmp);
}
简单对象的写入:
// 系统的类实例出来的对象 叫简单对象
// 例如: 字符串 数组 字典 二进制对象(NSData)
// 如果要写入一个数组 或者 字典 等容器类对象
// 那么这个容器当中 也要保存是 简单对象才能写入
- (void)writeFile
{
// 把字符串 存储到沙盒当中
NSString *str = @"第一章 盘古开天";
// xiaoshuo.txt
// 拼接文件存储的路径
NSString *filePath = [kDocuments stringByAppendingString:@"/xiaoshuo.txt"];
NSLog(@"%@",filePath);
// 进行简单对象的写入
// atomically 保护写入的作用
// 在写入过程中 出现意外情况 也可以写入成功
[str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
// 写入一个数组
NSArray *array = @[@"徐阳", @"赵姐", @"张文", @"壮壮用"];
// 获取写入的路径
NSString *arrayPath = [kDocuments stringByAppendingString:@"/array"];
// 写入
[array writeToFile:arrayPath atomically:YES];
NSLog(@"%@",arrayPath);
// 写入一个字典
NSDictionary *dic = @{@"name":@"wanglong", @"sex":@"nan"};
NSString *dicPath = [kDocuments stringByAppendingString:@"/dic.plist"];
[dic writeToFile:dicPath atomically:YES];
NSLog(@"%@",dicPath);
// 写入data数据
NSString *dataStr = @"哈哈哈";
NSData *data = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *dataPath = [kDocuments stringByAppendingString:@"/data"];
[data writeToFile:dataPath atomically:YES];
NSLog(@"%@",dataPath);
// data文件一般是存储图片的
// UIImagePNGRepresentation 把图片转化成data类型
NSData *imageData = UIImagePNGRepresentation([UIImage imageNamed:@"1"]);
NSString *imagePath = [kDocuments stringByAppendingString:@"/data"];
[imageData writeToFile:imagePath atomically:YES];
NSLog(@"%@",imagePath);
}
读取数据:
- (void)readFile
{
// 读取(按路径进行读取)
NSArray *document = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *arrayPath = [document[0] stringByAppendingString:@"/array.plist"];
// 从该路径进行读取
NSArray *array = [NSArray arrayWithContentsOfFile:arrayPath];
NSLog(@"%@",array);
NSString *imagePath = [document[0] stringByAppendingString:@"/data"];
NSData *data = [NSData dataWithContentsOfFile:imagePath];
UIImage *image = [UIImage imageWithData:data];
}
对文件夹进行创建 移动 复制 删除操作:
// 创建文件夹方法
- (void)createFile
{
// 1. 获取要创建文件夹的路径
NSString *downLoadPath = [kDocuments stringByAppendingPathComponent:@"/DownLoad"];
NSLog(@"%@",downLoadPath);
// 2. 创建文件管理器
// withIntermediateDirectories
// 是否覆盖之前的文件 如果填NO 就是不覆盖
// 不覆盖就相当于 创建文件夹失败
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isCreate = [fileManager createDirectoryAtPath:downLoadPath withIntermediateDirectories:YES attributes:nil error:nil];
// 打印是否创建成功
NSLog(@"%d",isCreate);
}
// 移动文件夹
- (void)moveFile
{
// 获取原路径
NSString *oldPath = [kDocuments stringByAppendingPathComponent:@"/DownLoad"];
// 获取新路径
NSString *newPath = [kCaches stringByAppendingPathComponent:@"/DownLoad"];
NSLog(@"%@",newPath);
// 创建文件管理对象
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isMove = [fileManager moveItemAtPath:oldPath toPath:newPath error:nil];
NSLog(@"%d",isMove);
}
// 拷贝文件夹
- (void)copyFile
{
// 原路径
NSString *oldPath = [kCaches stringByAppendingPathComponent:@"/DownLoad"];
// 新路径
NSString *newPath = [kDocuments stringByAppendingPathComponent:@"/DownLoad"];
NSLog(@"%@",newPath);
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isCopy = [fileManager copyItemAtPath:oldPath toPath:newPath error:nil];
NSLog(@"%d",isCopy);
}
// 删除文件夹
- (void)deleteFile
{
NSString *cachesPath = [kCaches stringByAppendingPathComponent:@"/DownLoad"];
NSLog(@"%@",cachesPath);
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isRemove = [fileManager removeItemAtPath:cachesPath error:nil];
NSLog(@"%d",isRemove);
}
// 判断文件夹是否存在
- (void)isExecutable
{
NSString *documentsPath = [kDocuments stringByAppendingPathComponent:@"/DownLoad"];
NSLog(@"%@",documentsPath);
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isExecutable = [fileManager isExecutableFileAtPath:documentsPath];
NSLog(@"%d",isExecutable);
}
数据的归档和反归档:
归档和反归档一般都用在复杂对象写入文件中
复杂对象写入步骤:
- 遵守一个协议 NSCoding (需要在写入的时候按照一定的规则进行写入 一定的编码格式去写入) 归档与反归档(序列与反序列)
- 重写(协议中)归档与反归档方法
- 创建一个复杂对象出来
- 创建一个归档对象
- 利用归档对象把复杂对象转化成data
- 把data写入文件 进行数据持久化
复杂类的属性归档与反归档:
// 归档方法
- (void)encodeWithCoder:(NSCoder *)aCoder
{
// 按照一定的编码格式归档
// 注意归档时候的key 要与 反归档时的一致
[aCoder encodeObject:self.name forKey:@"name"];
// 要选用与属性类型 一致的 编码方法
[aCoder encodeInteger:self.age forKey:@"age"];
// 一般统一使用对象类型的
[aCoder encodeObject:self.imageData forKey:@"imageData"];
}
// 反归档方法
- (instancetype)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;
}
将复杂类进行归档:
// 复杂对象写入文件
// 自己创建出来的类(例如 Student类)
// 写入的核心思想:
// 把复杂对象转化成 简单对象 进行写入
// 一般转化成 NSData对象进行写入
Student *student = [[Student alloc] init];
student.name = @"王龙";
student.age = 18;
student.imageData = UIImagePNGRepresentation([UIImage imageNamed:@"1"]);
// 创建一个可变data
NSMutableData *data = [NSMutableData data];
// 创建一个归档对象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
// 将复杂对象 通过归档对象 转化成data
[archiver encodeObject:student forKey:@"student"];
// 完成归档
[archiver finishEncoding];
// 实际上 通过 归档对象 把 复杂对象 写入data中
// 并且写入的标识 就是key
// 归档 与 反归档 不是数据持久化
// 只是把复杂对象 按照系统的编码格式 转化成data
// 真正的数据持久化 还是 写入文件
// NSLog(@"%@",data);
// 获取路径
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
// 拼接路径
NSString *path = [documentsPath stringByAppendingPathComponent:@"/SaveStudent"];
NSLog(@"%@",path);
// 写入文件
[data writeToFile:path atomically:YES];
// 释放归档对象
[archiver release];
// 反归档
// 从沙盒中 读取data数据
NSData *dataNew = [NSData dataWithContentsOfFile:path];
// 创建反归档对象
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:dataNew];
// 利用反归档对象 反归档出复杂对象
Student *stuNew = [unarchiver decodeObjectForKey:@"student"];
// 完成反归档
[unarchiver finishDecoding];
UIImage *image = [UIImage imageWithData:stuNew.imageData];
// 释放反归档对象
[unarchiver release];