SQL进行数据存储
进行数据存储需要先对文件的操作有一个了解, 第一步就是知道APP的数据是怎么储存的 存在哪里的
1.APP的沙盒机制
沙盒机制
1.每一个APP安装到手机上(或者模拟器上)都会生成三个文件夹 这三个文件夹叫做 沙盒 可以理解为这个APP的沙盒
2.并且每一个APP都是相对独立的 只能自己的应用去访问 不可以互相访问
3.文家中存储的是 代码以外的所有数据 (例如图片素材 声音 视频 文档等)也就是说咱们的持久化文件(缓存文件)可以存储到文件夹中
//每一次运行的时候 都是重新安装的过程 都会随机生成一个新的沙盒路径(名字 是随机的)
//注意:要获取的是当前的沙盒路径
//打印沙河路径 这个方法可以获取当前APP的沙盒路径
NSString *AppPath = NSHomeDirectory(); //打印这个路径
APP的沙河路径下 有三个文件夹
获取这个三个文件的路径
//Documents文件夹
//可以被iTunes备份 可以保存一些用户的数据 及 缓存文件等
//NSDocumentDirectory 要获取的文件夹路径
// NSUserDomainMask 搜索的范围
//YES 是否搜索全路径
NSArray *ducuments = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO);
// NSLog(@"%@",ducuments[0]);
// NSLog(@"%@",[ducuments lastObject]);
//Library
//可以被ituns备份
//Caches 主要以系统缓存文件
//Preferences 系统能够配置文件
NSArray *library = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, NO);
// NSLog(@"%@",library[0]);
// NSLog(@"%@",[library lastObject]);
//tem
//主要存储临时文件 当手机重新启动时 该文件夹的文件 会被删除(有可能 不关机 不重启 也被删除)
NSString *tem = NSTemporaryDirectory();
// NSLog(@"%@",tem);
2.在此之前 我们先学一个系统的单例类 NSFileManager <文件管理器>
这是一个单列类 可以对文件进行创建,删除,移动和赋值
(1) 创建一个文件夹
//在沙河的document文佳下面创建一个名为Download的文件夹
//把获取沙河路径的方法 写成宏定义
#define kDocumentPath [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]
#define kCaches [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject]
首先获取我们要创建文佳的路径 >>> document下的download文件夹
NSPath *path = [kDocumentPath stringByAppendingString:@"/download"];
//打印这个路径 写完运行之后 前往一下 看看有没有创建
NSLog(@"%@",path);
//创建文件管理器
NSFileManager *manager = [NSFileManager defaultManager];
// 创建文件夹
// withIntermediateDirectories 是否覆盖之前的文件 NO 就是被覆盖 创建文件夹失败
文件管理类创建文佳夹的方法 会返回一个BOOL值
BOOL isCreat = [manager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
NSLog(@"%d",isCreat);
// 移动文件夹
- (void)moveFile{
//获取原路径
NSString *oldPath = [kDocumentPath stringByAppendingPathComponent:@"/DwonLoad"];
NSString *newPath = [kCaches stringByAppendingPathComponent:@"/DwonLoad"];
//创建文件管理对象
NSFileManager *manage = [NSFileManager defaultManager];
//移动文件夹
BOOL isMove = [manage moveItemAtPath:oldPath toPath:newPath error:nil];
NSLog(@"%d",isMove);
}
//复制文件夹
- (void)copyFile{
//获取路径
NSString *path = [kCaches stringByAppendingString:@"/DwonLoad"];
NSFileManager *manager = [NSFileManager defaultManager];
NSString *document = [kDocumentPath stringByAppendingString:@"/DwonLoad"];
BOOL Iscopy = [manager copyItemAtPath:path toPath:document error:nil]; // 复制一个文件夹 也会把这个文件夹里面的内容复制过去
NSLog(@"%d",Iscopy);
NSLog(@"%@",document);
}
// 删除文件夹
- (void)deleteFile{
//获取路径
NSString *path = [kCaches stringByAppendingString:@"/DwonLoad"];
NSFileManager *manager = [NSFileManager defaultManager];
BOOL IsRemoved = [manager removeItemAtPath:path error:nil];
NSLog(@"%d",IsRemoved);
}
//判断文件夹是否存在
- (void)judgeExecutable{
//获取要判断的路径
NSString *path = [kCaches stringByAppendingPathComponent:@"/DwonLoad"];
NSFileManager *manager = [NSFileManager defaultManager];
BOOL IsExist = [manager isExecutableFileAtPath:path];
NSLog(@"%d",IsExist);
}
3.数据持久化 还需要学会 归档 与 反归档 >> NSKeyedArchiver
负载对象的写入文件 ,如自己创建的类(类似Students类) 写入的核心是把负载对象转换为简单对象 进行写入
创建一个Students类 包含属性
@property (nonatomic, retain) NSString *name; //姓名
@property (nonatomic, assign) NSInteger age; //年龄
@property (nonatomic, retain) NSData *imageData; //储存图片 的data
/*复杂对象写入步骤
1. 遵守NSCoding 协议(需要在写入的时候 按照一定的规则 进行写入 一定的编码格式) 归档与反归档 (序列与反序列)
2.重写(协议中)归档 与 反归档 方法
3.创建一个复杂对象
4.创建一个归档对象
5.把复杂对象归档成data文件
6.把data写入文件 进行出具持久化
*/
一般都是转化为NSData类型进行转换.
//将图片转换为NSData类型
Student *stu = [[Student alloc]init]; //创建一个复杂对象 , 自己创建的类
stu.name = @"ZMY"; //姓名
stu.age = 18; //姓名
stu.imageData = UIImagePNGRepresentation([UIImage imageNamed:@"007"]); //将图片转换为data // UIImagePNGRepresentation 是将PNG格式的图片转换为data 点进去这个方法 会发现还有一个将IJPG转为data的方法
现在开始进行归档
归档
// 创建一个可变的data 归档对象就是将要归档的对象转为data格式 存进我们创建的这个data中
NSMutableData *data = [NSMutableData data];
// 创建一个归档对象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
// 将负载对象通过归档对象 转化为data
[archiver encodeObject:stu forKey:@"Student"]; //完成归档 这个可以归档的时候给的标识符, 在反归档的时候要使用标识符才能取出我们要进行反归档的对象
// 完成归档
[archiver finishEncoding];
// 实际上 通过 归档对象 把复杂对象写入data中 并且写入的标识 就是key
// 归档与反归档不是数据持久化 只是把复杂对象 按照系统编码格式 转化成data
// 真正的数据持久化还是 写入文件
写入文件
NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
// 拼接文件
NSString *path = [document stringByAppendingPathComponent:@"/SaveStudent.txt"] ;
// 写入文件
[data writeToFile:path atomically:YES ];//保护写入作用, 若YES在写入过程中出现意外情况 也可以写入成功. 做法是先将数据写入内存中 再写到硬盘里. NO为不保护, 也就是直接写入硬盘中, 若发生意外会导致写入失败.
反归档
//和归档的步骤是类似的
// 获取路径 从沙盒中读取data数据
// NSData *dataNew = [NSData dataWithContentsOfFile:path];
// 创建反归档对象
NSKeyedUnarchiver *unArchive = [[NSKeyedUnarchiver alloc]initForReadingWithData:data]; //利用反归档对象 反归档处 复杂对象
Student *stu1 = [unArchive decodeObjectForKey:@"Student"];
[unArchive finishDecoding];//打印反归档出来的对象 看看里面的属性 是不是我们我们设置的属性
NSLog(@"%@",stu1.name);
NSLog(@"%ld",stu1.age);
UIImage *image = [UIImage imageWithData:stu1.imageData];// 如何把一个复杂的对象数组 写到文件中
// 遍历这个数组 把每一个复杂对象归档成简单对象(data)
// 然后再将data 保存到一个数组中
// 最后把数组写入文件中 进行持久化