ViewController.m
#import "ViewController.h"
#import "Student.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 苹果手机为了保证自己数据上的绝对安全,设计了沙盒机制,每一个应用程序都配备了自己的沙盒文件,每一次运行,文件夹的名字就会变成一个没有任何规律的字符串
// 找沙盒路径
// 第一个参数:当前要前往哪一个文件夹,前往documents文件用NSDocumentDirectory,64行那个,还可以前往caches文件夹,对应68行
// 第二个参数:访问的文件夹的类型,指定访问是用户文件夹
// 第三个参数:绝对路径(YES),相对路径(NO)
// 绝对路径是给系统来使用的,系统可以根据当前的路径找到文件夹,我们在操作文件的时候都是用绝对路径
// 相对路径只会把要前往的文件夹显示,其他的部分都是~,告诉程序员要去哪个文件
NSArray *sandBox=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(@"%@",sandBox[0]);
// 沙盒中一共有三个文件
// 1.是Documents文件:主要是用来储存用户想要储存的一些信息,比如收藏的信息或者自己设置的一些内容,所以我们做收藏功能就是往这个文件夹里写文件
// 2.Library文件夹是方便程序开发者使用的,主要操作它里面的两个文件夹,caches和Preferences
// caches:用来保存缓存文件,SDWebImage会把图片加到缓存文件中,所以清除缓存功能就是把这个文件夹删除
// Preferences:一般用来保存程序员设置的信息,比如NSUserDefaults就会把数据保存在这个文件夹里
// 3.tmp文件:一般存放临时内容
// 之前在沙盒里还有一个HelloWorld.app文件,在新的版本里已经移除了
// 把简单对象写入到本地,简单对象指的是NSString,NSArray等
// 1.先通过数组获取沙盒路径
NSArray *sandBox=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// 从数组里获取沙盒路径
NSString *sandBoxPath=sandBox[0];
// 要给写入的文件拼接一个路径,拼接方式有两种
// 1.
NSString *documentPath=[sandBoxPath stringByAppendingString:@"fuyu.txt"];
// 2.专门针对路径拼接的方法 比普通拼接多/
NSString *documentPath=[sandBoxPath stringByAppendingPathComponent:@"ufsd.txt"];
NSLog(@"%@",documentPath);
//-------把字符串写入到本地-------//
// 第一个参数:文件要保存的路径
// 第二个参数:对文件进行保护,YES;
// 第三个参数:编码
// 第四个参数:错误信息
NSString *str=@"讨厌宋显赫,讨厌讨厌讨厌";
[str writeToFile:documentPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
// 如果路径下有对应文件,则会把原来文件覆盖,如果没有,则创建一个新文件
// 把沙盒文件读出来
NSString *tempStr=[NSString stringWithContentsOfFile:documentPath encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@",tempStr);
//-------把数组写入到本地-------//
NSArray *arr=@[@"1",@"2",@"3",@"4",@"5"];
// 通过数组获取沙河地址
NSArray *sandBox=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// 用字符串保存沙盒路径
NSString *sandBoxPath=sandBox[0];
// 给要写入的文件拼接路径
NSString *documentPath=[sandBoxPath stringByAppendingPathComponent:@"arr.plist"];
// 把数组写入到本地
[arr writeToFile:documentPath atomically:YES];
NSLog(@"%@",doucumentPath);
// 把数组读出来
NSArray *tempArr=[NSArray arrayWithContentsOfFile:documentPath];
NSLog(@"%@",tempArr);
//------把字典写入到本地-------//
NSDictionary *dic=[NSDictionary dictionaryWithObjectsAndKeys:@"姗姗",@"name",@"28",@"age",@"女",@"sex", nil];
// 通过数组获得沙盒地址
NSArray *sandBox=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// 用字符串保存沙河路径
NSString *sandBoxPath=sandBox[0];
// 给要写入的文件拼接路径
NSString *documentPath=[sandBoxPath stringByAppendingPathComponent:@"dic.plist"];
// 将字典写入到本地
[dic writeToFile:documentPath atomically:YES];
NSLog(@"%@",documentPath);
// 把字典读出来
NSDictionary *tempDic=[NSDictionary dictionaryWithContentsOfFile:documentPath];
NSLog(@"%@",tempDic);
//-------把复杂对象写入到本地-------//
// 复杂对象写入到本地,主要指我们自己创建的对象写入到本地,也叫归档和反归档操作
// 用便利构造器的方法创建一个student对象
Student *stu=[Student studentWithName:@"姗姗" age:27 sex:@"女" hobby:@"sleep"];
// 1.通过数组获取沙盒路径
NSArray *sandBox=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// 2.用字符串接收沙盒路径
NSString *sandBoxPath=sandBox[0];
// 3.拼接文件夹路径,这个文件的扩展名是任意的
NSString *documentPath=[sandBoxPath stringByAppendingPathComponent:@"学生.avi"];
// 对对象进行归档操作
// 第一个参数:要实施归档的对象
// 第二个参数:路径
[NSKeyedArchiver archiveRootObject:stu toFile:documentPath];
NSLog(@"%@",documentPath);
// 反归档
Student *newStu=[NSKeyedUnarchiver unarchiveObjectWithFile:documentPath];
NSLog(@"%@",newStu.name);
// 创建三个学生
Student *stu1=[[Student alloc]initWithName:@"宋显赫" age:24 sex:@"男" hobby:@"睡觉"];
Student *stu2=[[Student alloc]initWithName:@"李牧燃" age:23 sex:@"女" hobby:@"玩"];
Student *stu3=[[Student alloc]initWithName:@"商帅" age:24 sex:@"男" hobby:@"学"];
NSArray *arr=@[stu1,stu2,stu3];
// 1.寻找沙盒路径
NSArray *sandBox=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// 2.用字符串接收沙盒路径
NSString *sandBoxPath=sandBox[0];
// 3.拼接
NSString *documentPath=[sandBoxPath stringByAppendingPathComponent:@"Student.plist"];
// 归档
[NSKeyedArchiver archiveRootObject:arr toFile:documentPath];
NSLog(@"%@",documentPath);
// 反归档,遍历学生的姓名
NSArray *arr1=[NSKeyedUnarchiver unarchiveObjectWithFile:documentPath];
for (Student *tempStu in arr1) {
NSLog(@"%@",tempStu.name);
}
NSLog(@"%@",[arr1[1]name]);
#warning summary :数据持久化的步骤
// 1.指定前往哪一个文件夹
// 2.用字符串接收路径
// 3.拼接文件路径
// 4.写入本地或者归档操作
// 5.反归档
// 注 :如果是复杂对象归档,要签订NSCoding方法,并且实现两个协议方法,放在数组里的复杂对象归档也要签协议
// 单例
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
[defaults setObject:@"123456" forKey:@"password"];
NSArray *sandBox=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(@"%@",sandBox[0]);
// 取值方法和字典相同,但是不可以用方括号的方法取值
NSLog(@"%@",[defaults objectForKey:@"password"]);
// NSUserDefaults一般存放的是小得数据,比如字符串等,它的用法和字典类似
//-------文件夹管理-------//
// 通过文件管理者对文件夹进行操作
// 1.在document文件夹下创建一个新的文件夹
NSArray *sandBox=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *sandBoxPath=sandBox[0];
NSLog(@"%@",sandBoxPath);
// 创建一个文件管理者
NSFileManager *manager=[NSFileManager defaultManager];
// 给要创建的文件夹拼接一个路径
NSString *filePath=[sandBoxPath stringByAppendingPathComponent:@"guyu"];// 不需要有扩展名
// 通过manager进行文件夹的创建
[manager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
NSLog(@"%@",filePath);
// 向新创建的文件夹里写入一个字符串
NSString *guyuPath=[filePath stringByAppendingPathComponent:@"字符串.txt"];
NSString *str=@"笨蛋";
[str writeToFile:guyuPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@",guyuPath);
// 移除文件夹
[manager removeItemAtPath:filePath error:nil];
NSLog(@"%@",guyuPath);// 移除之后就找不到文件夹了
NSArray *cache=NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath=cache[0];
// 移除缓存文件
[manager removeItemAtPath:cachePath error:nil];
NSLog(@"%@",sandBoxPath);
}
Student.h
#import <Foundation/Foundation.h>
#pragma mark 如果想实现归档和反归档的操作需要先签订一个协议NSCoding
@interface Student : NSObject<NSCoding>
@property(nonatomic,copy)NSString *name;
@property(nonatomic,assign)NSInteger age;
@property(nonatomic,copy)NSString *sex;
@property(nonatomic,copy)NSString *hobby;
// 针对这四条属性,写一个自定义初始化方法和便利构造器
-(instancetype)initWithName:(NSString *)name age:(NSInteger )age sex:(NSString *)sex hobby:(NSString *)hobby;
+(instancetype)studentWithName:(NSString *)name age:(NSInteger )age sex:(NSString *)sex hobby:(NSString *)hobby;
@end
Student.m
#import "Student.h"
@implementation Student
-(instancetype)initWithName:(NSString *)name age:(NSInteger )age sex:(NSString *)sex hobby:(NSString *)hobby
{
self=[super init];
if (self) {
self.name=name;
self.age=age;
self.sex=sex;
self.hobby=hobby;
}
return self;
}
+(instancetype)studentWithName:(NSString *)name age:(NSInteger )age sex:(NSString *)sex hobby:(NSString *)hobby
{
Student *stu=[[Student alloc]initWithName:name age:age sex:sex hobby:hobby];
return stu;
}
#pragma mark 签完NSCoding协议之后,需要实现两个协议方法,一个归档的时候使用的,另一个是反归档的时候使用的
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.name forKey:@"姓名"];
// key和反归档的保持一致
[aCoder encodeInteger:self.age forKey:@"年龄"];
[aCoder encodeObject:self.sex forKey:@"性别"];
[aCoder encodeObject:self.hobby forKey:@"爱好"];
// 使用encode方法 要和数据的类型相互匹配
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
self=[super init];
if (self) {
// 把数据根据之前的key在反编译出来
self.name = [aDecoder decodeObjectForKey:@"姓名"];
self.age = [aDecoder decodeIntegerForKey:@"年龄"];
self.sex = [aDecoder decodeObjectForKey:@"性别"];
self.hobby = [aDecoder decodeObjectForKey:@"爱好"];
}
return self;
}
@end