zoukankan      html  css  js  c++  java
  • iOS数据持久化(一)

    一、什么是数据持久化

    数据持久化及数据的永久存储,将数据保存在硬盘中,程序关闭,内存释放后,重新打开程序,可以继续访问之前保存的数据。

    二、数据持久化方式

    常见的数据持久化方式有以下几项:

    沙盒

    preference

    归档 / 反归档

    SQLite

    CoreData

    这篇只讲沙盒,preference,归档/反归档。

    1.沙盒

    沙盒是系统为每一个应用程序生成的一个特定文件夹   文件夹的名字由十六进制数据组成,每一个应用程序的沙盒文件名都是不一样的,是由系统随机生成的。

        //获取沙盒主目录
        NSString *path = NSHomeDirectory();
        NSLog(@"%@",path);

    沙盒下每个文件夹的路径及作用

    //Documents  存放的一些比较重要的文件,但是存入Documents中的文件不能过大
        //如何获取Documents文件目录
        NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
        NSLog(@"%@",documentsPath);
        //用firstobject取值是因为该方法一开始使用mac端OS X开发,对于PC端用户可以有多个用户,所以可以取到很多user的路径,但是该方法现在用于手机开发,手机端只有一个用户,所以获得的用户只有一个,lastobject也是可以的。
        
        //Library:是一个资源库,存储一些不太重要的数据,相对比较大一些,里边有两个子文件夹;
        NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)firstObject];
        //Caches:缓存文件,图片缓存,音频,视频。网页资源。应用程序清除缓存,就是清除该文件夹
        NSString *cachesPath  = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)firstObject];
        //Preferences:系统偏好设置,用户对应程序的设置,比如用户名和用户密码,preference路径无法找到,通过NSUserDefaults
        
        //temp:存放临时文件,比如下载的压缩包zip,解压后理解把压缩包删除
        NSString *tempPath = NSTemporaryDirectory();
        NSLog(@"%@",tempPath);
        //bundle:ios8之前,包和沙河在同一个目录下,之后.app单独存储到一个独立的文件目录下。 .app 文件 readOnly。从appStore下载下来的是这个包,程序上传的时候也是这个包
        NSString *bundlepath = [[NSBundle mainBundle] bundlePath];
        NSLog(@"%@",bundlepath);
        // NSSearchPathDirectory 这个类是用来查找文件目录的
        //第一个参数:文件名称
        //第二个参数,确定搜索域
        //第三个参数:确定相对路径还是绝对路径。YES绝对,NO相对

    文件相关操作

    /**
     *  文件删除
     */
    - (void)deleteFile {
        NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
    
         NSString *imagePath = [cachesPath stringByAppendingPathComponent:@"iamge"];
        NSLog(@"%@",imagePath);
        //创建文件管理者
        NSFileManager *fileManager =  [NSFileManager defaultManager];
        //判断文件是否存在
        BOOL isExist = [fileManager fileExistsAtPath:imagePath];
        if (!isExist) {
            BOOL isSuccess = [fileManager createDirectoryAtPath:imagePath withIntermediateDirectories:YES attributes:nil error:nil];
            NSLog(@"%@",isSuccess ? @"创建成功" : @"创建失败");
        }
        //删除文件
        if ([fileManager fileExistsAtPath:imagePath]) {
            BOOL isSucess = [fileManager removeItemAtPath:imagePath error:nil];
            NSLog(@"%@",isSucess ? @"删除成功" : @"删除失败");
        }
    }
    /**
     *  移动
     */
    - (void)moveFile {
        NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
        
        NSString *imagePath = [cachesPath stringByAppendingPathComponent:@"iamge"];
        NSLog(@"%@",imagePath);
        //创建文件管理者
        NSFileManager *fileManager =  [NSFileManager defaultManager];
        //判断文件是否存在
        BOOL isExist = [fileManager fileExistsAtPath:imagePath];
        if (!isExist) {
            BOOL isSuccess = [fileManager createDirectoryAtPath:imagePath withIntermediateDirectories:YES attributes:nil error:nil];
            NSLog(@"%@",isSuccess ? @"创建成功" : @"创建失败");
        }
        //删除文件
        //    if ([fileManager fileExistsAtPath:imagePath]) {
        //        BOOL isSucess = [fileManager removeItemAtPath:imagePath error:nil];
        //        NSLog(@"%@",isSucess ? @"删除成功" : @"删除失败");
        //    }
        //拷贝文件
        //    把包中的plist文件拷贝到image文件夹下
        NSString *plistInBundlePath = [[NSBundle mainBundle] pathForResource:@"NB.plist" ofType:nil];
        
        NSString *nBPath = [imagePath stringByAppendingPathComponent:@"NB.plist"];
        // 拷贝,
        if (![fileManager fileExistsAtPath:nBPath]) {
            BOOL isSuccess = [fileManager copyItemAtPath:plistInBundlePath toPath:nBPath error:nil];
            NSLog(@"%@",isSuccess ? @"拷贝成功" : @"拷贝失败");
        }
        
        NSString *toPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject];
        BOOL isSuccess = [fileManager moveItemAtPath:nBPath toPath:[toPath stringByAppendingPathComponent:@"NB.plist"] error:nil];
        NSLog(@"%@",isSuccess ? @"移动成功" : @"移动失败");
        
    }
    //字符串写入文件
    - (void)writeToFile {
        //简单对象写入文件:字符串,数组,字典,二进制流 只有这些简单对象支持文件的写入
        //如果要写入的文件数据时数组,字典,必须要保证数组,字典中的数据 也是简单对象(如果是复杂对象,请参照后边的归档,反归档)
        //将字符串写入Documents文件夹下
        NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject];
        NSString *toPath = [documentsPath stringByAppendingPathComponent:@"string.txt"];
        NSString *string = @"string-string-string-";
        //第一个参数,要写入的文件路径,如果不存在文件,会自动创建    第二个参数,原子性,判断是否需要生成辅助文件,保护在多线程下安全    第三个参数,编码格式    第四个参数,错误信息
        NSError *error = nil;
        BOOL isSuccess = [string writeToFile:toPath atomically:YES encoding:NSUTF8StringEncoding error:&error];
        NSLog(@"%@",isSuccess ? @"写入成功" : @"写入失败");
        
        NSString *str = [NSString stringWithContentsOfFile:toPath encoding:NSUTF8StringEncoding error:nil];
        NSLog(@"%@",str);
    }
    //数组写入文件
    - (void)writeArray {
        
        NSString *str = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)firstObject];
        NSString *toPath = [str stringByAppendingPathComponent:@"array.txt"];
        NSArray *array = @[@"123",@"123"];
        BOOL isSuccess = [array writeToFile:toPath atomically:YES];
        NSLog(@"%@",isSuccess ? @"写入成功" : @"写入失败");
        
        NSArray *arr = [NSArray arrayWithContentsOfFile:toPath];
        NSLog(@"%@",arr);
    
    }
    //字典写入文件
    - (void)writeDic {
        NSDictionary *dic = @{@"key":@"value"};
        NSString *str = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)firstObject];
        NSString *toPath = [str stringByAppendingPathComponent:@"dictonry.txt"];
        BOOL isSuccess = [dic writeToFile:toPath atomically:YES];
        NSLog(@"%@",isSuccess ? @"成功" : @"失败");
        NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:toPath];
        NSLog(@"%@",dict);
    }
    //NSData写入文件
    - (void)writeData {
        NSString *tempPath = NSTemporaryDirectory();
        NSString *toPath = [tempPath stringByAppendingPathComponent:@"data.txt"];
        NSString *string = @"datadata";
        NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
        BOOL isSuccess = [data writeToFile:toPath atomically:YES];
        NSLog(@"%@",isSuccess ? @"成功" : @"失败");
        NSData *getData = [NSData dataWithContentsOfFile:toPath];
        NSString *str = [[NSString alloc] initWithData:getData encoding:NSUTF8StringEncoding];
        NSLog(@"%@",str);
    }

    2.preference

    //Preference
    - (void)writeToPreference {
        // NSUserDefaults 继承自NSObject ,单例     通过kvc模式赋值
        NSLog(@"%@",NSHomeDirectory());
        //创建用户索引对象
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        [defaults setInteger:100 forKey:@"money"];
        //立即同步操作      对preference中的文件进行修改后,立即同步
        [defaults synchronize];
        NSInteger money = [defaults integerForKey:@"money"];
        NSLog(@"%ld",money);
        [defaults setInteger:10000 forKey:@"MyMoney"];
        [defaults synchronize];
        
        NSInteger you = [defaults integerForKey:@"you"];
        NSLog(@"%ld",(long)you);
        if (money < 10) {
            NSLog(@"there is no money");
        } else {
            NSLog(@"-100");
            money -= 100;
            [defaults setInteger:40 forKey:@"money"];
            [defaults setInteger:1000 forKey:@"YourMoney"];
        }
        // NSUserDefaults 一般存储一些比较小的数据,大部分用来存数值
        
        //例子:判断用户是否第一次登陆
        NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
        BOOL isFirst = [userDefault boolForKey:@"isFirst"];
        [userDefault setBool:YES forKey:@"isFirst"];
        [userDefault synchronize];
        if (!isFirst) {
            NSLog(@"第一次登陆");
        } else {
            NSLog(@"不是第一次登陆");
        }
    }

    3.归档 / 反归档

    复杂对象写入文件需要使用归档 ,读取需要使用反归档,不能直接写入文件,数组中有复杂对象也要使用归档 / 反归档

    复杂对象使用行归档和反归档,需要遵循NSCoding协议,并实现协议中- (void)encodeWithCoder:(NSCoder *)aCoder;   - (id)initWithCoder:(NSCoder *)aDecoder; 两个方法

     

    新建Person类

    在Person.h中 遵循协议

    //
    //  Person.h
    //  07.24-DataPersistiser
    //
    //  Created by lanouhn on 14/7/24.
    //  Copyright (c) 2014年 LCD. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject <NSCoding>
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, copy) NSString *gender;
    @property (nonatomic, assign) NSInteger age;
    @end

    在Person.m中实现协议方法

    //
    //  Person.m
    //  07.24-DataPersistiser
    //
    //  Created by lanouhn on 14/7/24.
    //  Copyright (c) 2014年 LCD. All rights reserved.
    //
    
    #import "Person.h"
    
    @implementation Person
    
    //当要归档时,对象会自动触发这个方法
    - (void)encodeWithCoder:(NSCoder *)aCoder {
        [aCoder encodeObject:self.name forKey:@"name"];
        [aCoder encodeObject:self.gender forKey:@"gender"];
        [aCoder encodeObject:@(self.age) forKey:@"age"];
    }
    - (id)initWithCoder:(NSCoder *)aDecoder {
        self = [super init];
        if (self) {
            self.name = [aDecoder decodeObjectForKey:@"name"];
            self.gender = [aDecoder decodeObjectForKey:@"gender"];
            self.age = [[aDecoder decodeObjectForKey:@"age"] integerValue];
        }
        return self;
    }
    @end

    归档 / 反归档

    - (void)archiver {
        
        //把复杂文件写入文件,先转化为nsdata对象
        //归档:归档的实质就是把其他类型的数据(person),先转化为NSData,再写入文件。
        Person *person = [[Person alloc] initWithName:@"rose" gender:@"girl" age:25];
        //    NSKeyedArchiver  压缩工具类,继承自NSCoder,主要用于编码
        NSMutableData *data = [NSMutableData data] ;
        NSKeyedArchiver *achiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
        //使用压缩工具讲Person压到data中
        [achiver encodeObject:person forKey:@"person"];
        //完成压缩,停掉压缩工具
        [achiver finishEncoding];
    
        
        NSString *homePath = NSHomeDirectory();
        NSString *toPath = [homePath stringByAppendingPathComponent:@"person.txt"];
        BOOL isSuccess = [data writeToFile:toPath atomically:YES];
        NSLog(@"%@",isSuccess ? @"成功" : @"失败");
        
        //复杂对象的读取,反归档
        //    NSKeyedUnarchiver
        NSData *getData = [NSData dataWithContentsOfFile:toPath];
        NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:getData];
        //解压
        Person *p1 = [unArchiver decodeObjectForKey:@"person"];
        [unArchiver finishDecoding];
    }
     //集合NSArray NSDictionary 如果想进行归档和反归档,那么它里边存储的元素也要遵循NSCoding协议
        Person *person1 = [[Person alloc] initWithName:@"jack" gender:@"" age:20];
        Person *person2 = [[Person alloc] initWithName:@"rose" gender:@"" age:20];
        NSArray *array = @[person1,person2];
    
        
        NSMutableData *data = [NSMutableData data];
        
        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
        [archiver encodeObject:array forKey:@"array"];
        [archiver finishEncoding];
    
        
        NSString *tmpPath = NSTemporaryDirectory();
        NSString *toPath = [tmpPath stringByAppendingString:@"array.txt"];
        
        BOOL isSuccess = [data writeToFile:toPath atomically:YES];
        NSLog(@"%@",isSuccess ? @"成功" : @"失败");
        //反归档
        NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
        NSArray *unArchiverArray = [unArchiver decodeObjectForKey:@"array"];
  • 相关阅读:
    uva 11080(二分图染色)
    poj 3255(次短路)
    uva 707(记忆化搜索)
    uva 436(floyd变形)
    uva 11748(求可达矩阵)
    uva 11573(bfs)
    Codeforces Round #226 (Div. 2) 解题报告
    uva 11354(最小瓶颈路--多组询问 MST+LCA倍增)
    uva 534(最小瓶颈路)
    uva 538(简单图论 入度出度)
  • 原文地址:https://www.cnblogs.com/code-cd/p/4803218.html
Copyright © 2011-2022 走看看