数据持久化 将数据写入到本地 文件管理

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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值