• 数据持久化-存取方式总结&应用沙盒&文件管理NSFileManager


    iOS应用数据存储的常用方式:
     1.XML属性列表     (plist归档)
     2.NSUserDefaults  (偏好设置)
     3.NSKeyedArchiver  归档(加密形式)
     4.SQLite3     (嵌入式数据库)
     5.Core Data    (面向对象方式的嵌入式数据库)
     
     
    一.应用沙盒
     
    1.iOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒
      说明:
        a.每个应用程序都有自己的存储空间
        b.应用程序无法翻过自己的围墙去访问别的存储空间的内容
        c.应用程序请求的数据都要通过权限检测,假如不符合条件的话,不会被放行。
     
    2.mac下查看沙盒路径
      step1.显示Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles -bool true
      step2.进入如下路径/Users/username/Library/Application Support/iPhone Simulator/,即可找到各个程序的应用沙盒
     
    3.沙盒目录结构
         默认情况下,每个程序的沙盒含有3个文件夹:Documents, Library 和 tmp:
        
       

      Documents:保存应用运行时生成的需要持久化的数据。例如,游戏应用可将游戏存档保存在该目录。iTunes同步设备时备份该目录

      Library/Preference:保存应用的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找应用的设置信息。iTunes同步设备时备份该目录

      Library/Caches:保存应用运行时生成的需要持久化的数据,一般存储体积大、不需要备份的非重要数据,iTunes同步设备时不会备份该目录。

      tmp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录

     

    4.获取目录路径代码:

        //获取沙盒路径
        NSString *home = NSHomeDirectory();
        
        //1.获取Document路径
        //1.1通过文件名获取,因为ios以后的新版本可能修改目录名,不建议使用
        NSString *documentPath1 = [home stringByAppendingPathComponent:@"Documents"];
        //1.2通过系统方法获取,建议使用
        NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentPath2 = [array objectAtIndex:0];
        
        //2.获取Library/Cache目录,获取方式同Document,下面是系统方法
        NSArray *cache = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
        NSString *cachePath = [cache objectAtIndex:0];
        
        //3.获取Library/Preferences也可食用1.1的方式获取,但因为是保存setting设置,一般通过NSUserDefaults直接存储
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        [defaults setObject:@"myname" forKey:@"username"];
        
        //4.获取tmp目录
        NSString *tmpPath = NSTemporaryDirectory();

    如何在沙盒中操作文件夹和文件,系统提供了

    二.文件存储

    1.XML属性列表(plist归档)

      如果对象是NSStringNSDictionaryNSArrayNSDataNSNumber等类型,就可以使用writeToFile:atomically:方法直接将对象写到属性列表文件中,使用

    dataWithContentsOfFile方法读取plist文件中的信息并实例化对象

        NSString *tmpPath = NSTemporaryDirectory();
        NSString *path = [tmpPath stringByAppendingPathComponent:@"test.plist"];
        
        // 将数据封装成字典
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        [dict setObject:@"jason" forKey:@"name"];
        [dict writeToFile:path atomically:YES];
        
        // 读取plist的内容,实例化NSDictionary
        NSDictionary *dictPlist = [NSDictionary dictionaryWithContentsOfFile:path];
        NSLog(@"name:%@", [dictPlist objectForKey:@"name"]);

    2.NSUserDefaults(偏好设置)

       使用set方法保存不同类型的对象,使用xxxForKey方法获取值

        //偏好设置
        NSUserDefaults *dft = [NSUserDefaults standardUserDefaults];
        [dft setObject:@"jason" forKey:@"username"];
        [dft setFloat:1.77f forKey:@"high"];
        [dft setBool:YES forKey:@"auto_logon"];
        
        //读取偏好设置
        NSUserDefaults *dft2 = [NSUserDefaults standardUserDefaults];
        NSString *name = [dft2 objectForKey:@"username"];
        float h = [dft2 floatForKey:@"high"];
        BOOL al = [dft2 boolForKey:@"auto_logon"];
        NSLog(@"%@--%f--%hhd",name,h,al);

      自动在Library/Preferences/生成项目名开头的plist文件

      

    3.NSKeyedArchiver  归档(加密形式)

      机制类似于java的对象序列化,归档是指将对象保存到文件,反归档(读档)是指将文件内容解析成对象

      3.1 NSStringNSDictionaryNSArrayNSDataNSNumber等类型可以直接用NSKeyedArchiver进行归档和反归档

      3.2 任何遵守了NSCoding协议的对象,都可以进行归档和反归档

      3.3 NSCoding协议需要实现两个方法:
        - (void)encodeWithCoder:(NSCoder *)encoder //将对象归档的时候会调用(将对象写入文件之前会调用),用来说明哪些属性需要归档,怎样归档

        -(id)initWithCoder:(NSCoder *)decoder //当从文件中反归档对象时调用,用来说明哪些属性需要反归档,怎样反归档

        注:如果父类中也有属性需要归档或者反归档,必须调用superencodeWithCoder:initWithCoder:方法

      3.4代码实例:

        3.4.1 对象类:Person和子类Man

    //  Person.h
    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject<NSCoding>
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, assign) int age;
    @property (nonatomic, assign) double height;
    @end
    
    //  Person.m
    
    #import "Person.h"
    
    @implementation Person
    
    //归档时调用
    - (void)encodeWithCoder:(NSCoder *)coder
    {
        [coder encodeObject:_name forKey:@"name"];
        [coder encodeInt:_age forKey:@"age"];
        [coder encodeDouble:_height forKey:@"height"];
    }
    
    //反归档时调用调用的初始化方法
    -(id)initWithCoder:(NSCoder *)deCode
    {
        if (self = [super init]) {
            _name   = [deCode decodeObjectForKey:@"name"];
            _age    = [deCode decodeIntForKey:@"age"];
            _height = [deCode decodeDoubleForKey:@"height"];
        }
        return self;
    }
    
    @end
    
    
    
    //  Man.h继承自Person
    #import "Person.h"
    
    @interface Man : Person
    @property (nonatomic, copy) NSString *sex;
    @end
    
    //  Man.m
    #import "Man.h"
    
    @implementation Man
    
    //归档时调用
    -(void)encodeWithCoder:(NSCoder *)coder
    {
        //首先调用父类的归档方法
        [super encodeWithCoder:coder];
        [coder encodeObject:_sex forKey:@"sex"];
    }
    
    //反归档时调用的初始化方法
    -(id)initWithCoder:(NSCoder *)deCode
    {
        if (self = [super initWithCoder:deCode]) {
            _sex = [deCode decodeObjectForKey:@"sex"];
        }
        return  self;
    }
    
    @end

        3.4.1 归档和反归档的实现方法

    NSString *tmpPath = NSTemporaryDirectory();
        NSString *path1 = [tmpPath stringByAppendingPathComponent:@"person.data"];
        NSString *path2 = [tmpPath stringByAppendingPathComponent:@"man.data"];
        
        Person *p = [[Person alloc]init];
        p.name = @"a";
        p.age = 11;
        p.height = 1.70f;
        
        Man *m = [[Man alloc]init];
        m.name = @"b";
        m.age = 12;
        m.height = 1.77f;
        m.sex = @"male";
        
        //归档
        [NSKeyedArchiver archiveRootObject:p toFile:path1];
        [NSKeyedArchiver archiveRootObject:m toFile:path2];
        
        //反归档
        Person *p2 = [NSKeyedUnarchiver unarchiveObjectWithFile:path1];
        Man *m2 = [NSKeyedUnarchiver unarchiveObjectWithFile:path2];
        NSLog(@"%@--%d--%f",p2.name,p2.age,p2.height);
        NSLog(@"%@--%d--%f---%@",m2.name,m2.age,m2.height,m2.sex);

      4.SQLite3 & Core Data

      都是对数据做操作,CoreData只是在SQLite3的基础上做了一层面向对象的封装,类似于Hibernate,暂不总结,后续会新写文章总结

    三.NSFileManager

    参考文章:http://www.cnblogs.com/xyzlmn/p/3196930.html

    创建文件夹:

     

    //创建文件夹
    -(void *)createDir{
        NSString *documentsPath =[self dirDoc];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
        // 创建目录
        BOOL res=[fileManager createDirectoryAtPath:testDirectory withIntermediateDirectories:YES attributes:nil error:nil];
        if (res) {
            NSLog(@"文件夹创建成功");
        }else
            NSLog(@"文件夹创建失败");
     }



    创建文件

     

    //创建文件
    -(void *)createFile{
        NSString *documentsPath =[self dirDoc];
        NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];
        BOOL res=[fileManager createFileAtPath:testPath contents:nil attributes:nil];
        if (res) {
            NSLog(@"文件创建成功: %@" ,testPath);
        }else
            NSLog(@"文件创建失败");
    }


    写数据到文件:

     

    //写文件
    -(void)writeFile{
        NSString *documentsPath =[self dirDoc];
        NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
        NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];
        NSString *content=@"测试写入内容!";
        BOOL res=[content writeToFile:testPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
        if (res) {
            NSLog(@"文件写入成功");
        }else
            NSLog(@"文件写入失败");
    }
    

    读文件数据:

     

    //读文件
    -(void)readFile{
        NSString *documentsPath =[self dirDoc];
        NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
        NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];
    //    NSData *data = [NSData dataWithContentsOfFile:testPath];
    //    NSLog(@"文件读取成功: %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        NSString *content=[NSString stringWithContentsOfFile:testPath encoding:NSUTF8StringEncoding error:nil];
        NSLog(@"文件读取成功: %@",content);
    }

    文件属性:

     

    //文件属性
    -(void)fileAttriutes{
        NSString *documentsPath =[self dirDoc];
        NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];
        NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:testPath error:nil];   
        NSArray *keys;
        id key, value;
        keys = [fileAttributes allKeys];
        int count = [keys count];
        for (int i = 0; i < count; i++)
        {
            key = [keys objectAtIndex: i];
            value = [fileAttributes objectForKey: key];
            NSLog (@"Key: %@ for value: %@", key, value);
        }
    }
    

    删除文件:

      

    //删除文件
    -(void)deleteFile{
        NSString *documentsPath =[self dirDoc];
        NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];   
        BOOL res=[fileManager removeItemAtPath:testPath error:nil];
        if (res) {
            NSLog(@"文件删除成功");
        }else
            NSLog(@"文件删除失败");   
        NSLog(@"文件是否存在: %@",[fileManager isExecutableFileAtPath:testPath]?@"YES":@"NO");
    }

    遍历子文件夹:

        NSString *home = NSHomeDirectory();
        NSFileManager *fileManage = [NSFileManagerdefaultManager];
        NSArray *file = [fileManage subpathsOfDirectoryAtPath: home error:nil];
        NSLog(@"%@",file);
        NSArray *files = [fileManage subpathsAtPath: home ];
        NSLog(@"%@",files);

  • 相关阅读:
    【每日scrum】5.3
    Scrum仪式之Sprint计划会议
    软工结队开发--成员介绍
    java反射保存
    java后台开发传输乱码&&接口post传参失败
    润乾报表之分组
    润乾报表之居中无效(去空格)
    润乾报表之日期格式、小数位数
    润乾报表之序号、固定行数、统计
    润乾报表之条形码
  • 原文地址:https://www.cnblogs.com/anywherego/p/3542812.html
Copyright © 2020-2023  润新知