zoukankan      html  css  js  c++  java
  • iOS:文件归档和解归档的详解和使用

    文件归档和解归档:

    用途
    所谓文件归档,就是把需要存储的对象数据存储到沙盒的Documents目录下的文件中,即存储到了磁盘上,实现数据的持久性存储和备份。解归档,就是从磁盘上读取该文件下的数据,用来完成用户的需求。对象归档是将对象归档以文件的形式保存到磁盘中(也称为序列化,持久化),使用的时候读取该文件的保存路径读取文件的内容(也称为接档,反序列化),(对象归档的文件是保密的,在磁盘上无法查看文件中的内容,属性列表是明文的,可以查看)。
     
    区别:
    通过文件归档产生的文件是不可见的,如果打开归档文件的话,内容是乱码的;它不同于属性列表和plist文件是可见的,正因为不可见的缘故,使得这种持久性的数据保存更有可靠性。
     
    种类:
    (1)OC内置对象的单个对象归档、解归档 (2)自定义对象的单个对象归档 、解归档 (3)多个对象归档、解归档
     
    步骤:
    首先,获取沙盒的Documents目录,并通过拼接方式在该目录下创建一个文件夹用来存储对象数据;
     
    其次,准备需要归档的对象数据;
     
    然后,用相应的方法对数据进行归档,即将数据存储到该文件夹下;
     
    最后,用相应的方法对数据进行解归档,即从该文件夹下获取存储的数据。
     
    各自需要的方法如下:
     
    1、NSKeyedArchiver 归档、解归档(只适用于OC里面内置的对象)

       + (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;//归档

       + (id)unarchiveObjectWithFile:(NSString *)path;//接归档

    2、NSKeyedArchiver 归档、解归档(自定义的对象,必须要实现<NSCoding>协议)

      - (void)encodeWithCoder:(NSCoder *)aCoder;//归档的协议方法,序列化

      - (id)initWithCoder:(NSCoder *)aDecoder;//解归档的协议方法,反序列化

      + (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;//归档

      + (id)unarchiveObjectWithFile:(NSString *)path;//接归档

    3、对多个对象进行归档、解归档

      - (instancetype)initForWritingWithMutableData:(NSMutableData *)data;//用一个可变的data创建归档对象

      - (void)encodeObject:(id)objv forKey:(NSString *)key;//将对象归档

      - (void)finishDecoding//完成归档(必须执行)

      - (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile//将数据写进归档文件中

      - (instancetype)initForReadingWithData:(NSData *)data;//用一个data创建解归档对象,这个data由文件中获取而来

      - (id)decodeObjectForKey:(NSString *)key;//解归档

    文件归档和解归档的使用:

    一、对内置单个对象进行归档和解归档

    1.获取归档文件的路径(归档文件名可以自己随意取名)

    1       NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    2 
    3       NSString *documentPath = [documents lastObject];
    4 
    5       NSString *archiveFileName = [documentPath stringByAppendingPathComponent:@"array.arc"];

    2.准备归档的对象数据   

    1     NSArray *array = @[@1,@5,@3,@3,@4,@2];

    3.对数据进行归档(根据flag标识进行判断,如果返回的是YES,归档成功;反之,归档失败)

    1     if([NSKeyedArchiver archiveRootObject:array toFile:archiveFileName])
    2 
    3      {
    4 
    5          NSLog(@"归档对象成功");
    6 
    7      } 

    4.对数据进行解归档

    1    NSArray *array2 = [NSKeyedUnarchiver unarchiveObjectWithFile:archiveFileName];

    二、对自定义的单个对象进行归档和解归档(由于自定义对象不具有归档的性质,所以要实现归档和解归档,首先必须实现<NSCoding>协议)

    1.自定义一个归档对象类,实现协议

    Person.h  

    1 #import <Foundation/Foundation.h>
    2 @interface Person : NSObject<NSCoding>
    3 @property (copy,nonatomic)NSString *name;
    4 @property (assign,nonatomic)NSInteger age;
    5 @property (assign,nonatomic)char gender;
    6 -(id)initWithName:(NSString*)name andAge:(NSInteger)age andChar:(char)gender;
    7 @end

    Person.m

     1 #import "Person.h"
     2 @implementation Person
     3 -(id)initWithName:(NSString*)name andAge:(NSInteger)age andChar:(char)gender
     4 {
     5     self = [super init];
     6     if(self)
     7     {
     8         _name = [name copy];
     9         _age = age;
    10         _gender = gender;
    11     }
    12     return self;
    13 }
    14 -(NSString*)description
    15 {
    16     return [NSString stringWithFormat:@"name:%@,age:%ld,gender:%c",_name,_age,_gender];
    17 }
    18 #pragma mark -<NSCoding>
    19 //归档的协议方法
    20 -(void)encodeWithCoder:(NSCoder *)aCoder//将归档对象序列化
    21 {
    22     [aCoder encodeObject:_name forKey:@"name"];
    23     [aCoder encodeInteger:_age forKey:@"age"];
    24     [aCoder encodeInt:_gender forKey:@"gender"];
    25 }
    26 //解归档的协议方法
    27 -(id)initWithCoder:(NSCoder *)aDecoder //将归档对象反序列化
    28 {
    29     self = [super init];
    30     if(self)
    31     {
    32         _name = [[aDecoder decodeObjectForKey:@"name"] copy];
    33         _age = [aDecoder decodeIntegerForKey:@"age"];
    34         _gender = [aDecoder decodeIntForKey:@"gender"];
    35     }
    36     return self;
    37 }
    38 @end

    2.获取归档文件的路径(归档文件名可以自己随意取名)

    1 NSString *homePath = NSHomeDirectory();
    2     
    3 NSString *documentPath = [homePath stringByAppendingPathComponent:@"documents"];
    4     
    5 NSString *arcviFileName = [documentPath stringByAppendingPathComponent:@"person.arc"];

    3.创建该类归档对象并将其初始化 

    1 Person *person = [[Person alloc]initWithName:@"Tom" andAge:23 andChar:'M'];

    4.将归档对象归档 

    1 if([NSKeyedArchiver archiveRootObject:person toFile:arcviFileName])
    2     {
    3         NSLog(@"归档成功");
    4     }
    5     else
    6     {
    7         NSLog(@"归档失败");
    8     }

    5.将归档的对象解归档

    1 Person *person2 = [NSKeyedUnarchiver unarchiveObjectWithFile:arcviFileName];

    三、对多个对象进行归档和解归档(前面的两种方式都是针对于单个对象进行归档和解归档,如果需要对多个对象进行归档,它们就无用武之地了,局限性很大,因此,这里介绍一个新的归档方式,多对象归档和解归档)

    1.获取的文件路径(归档文件名可以自己随意取名)

    1 NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    2     NSString *documentPath = [documents lastObject];
    3     NSString *archiveFileName = [documentPath stringByAppendingPathComponent:@"objects.arc"];

    2.准备要归档的多个归档对象数据

    1 NSString *useName = @"admin";
    2 NSArray *scores = @[@90,@89,@90.5,@98];
    3 NSString *adress = @"北京市昌平区东三旗";

    3.对归档对象进行归档

     1   //归档多个对象(将多个对象读到data中)
     2     //1.用一个可变的data对象创建归档对象
     3     NSMutableData *data = [[NSMutableData alloc]init];
     4     NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
     5     
     6     //2.归档多个对象
     7     [archiver encodeObject:useName forKey:@"userName"];
     8     [archiver encodeObject:scores forKey:@"scores"];
     9     [archiver encodeObject:adress forKey:@"adress"];
    10     
    11     //3.完成归档(必须要实现的方法,要不然归档失败)
    12     [archiver finishEncoding];
    13     
    14     //4.将可变的data写进文件
    15     [data writeToFile:archiveFileName atomically:YES];

    说明:这种归档方式,其实就是先将所有的要归档的对象先存入到一个可变的NSMutableData对象data中,然后通过data创建的归档对象将data的数据归档到归档文件中就是了。

    4.将归档对象进行解归档

     1     //解归档多个对象
     2     //1.从文件中读出一个data
     3     NSData *data2 = [NSData dataWithContentsOfFile:archiveFileName];
     4     //2.由data创建解归档对象
     5     NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data2];
     6     
     7     //3.按照key解出多个对象
     8     NSString *userName2 = [unarchiver decodeObjectForKey:@"userName"];
     9     NSArray *scores2 = [unarchiver decodeObjectForKey:@"scores"];
    10     NSString *adress2 = [unarchiver decodeObjectForKey:@"adress"];
    11     
    12     NSLog(@"uesrName:%@,scores:%@,adress:%@",userName2,scores2,adress2);

    说明:这种解归档方式,其实就是从归档文件先读取data,然后通过data创建解归档对象根据指定的键将多个对象都解归档出来就是了。

    演示如下:

    2015-09-20 11:16:56.563 05-一个文件多个归档[908:42275] uesrName:admin,scores:(
        90,
        89,
        "90.5",
        98
    ),adress:北京市昌平区东三旗
  • 相关阅读:
    QK对中断的特殊处理
    程序控制的软件复位方法
    软件的按契约设计(DbC---Design by Contract)
    Arduino平台基于DbC的软件调试
    软件测试中的测不准原理
    关于嵌入式软件
    程序设计的SOLID原则
    CPS---(Cyber-Physical Sytem,信息物理融合系统)
    QP之QF原理
    QP之QEP原理
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/4823096.html
Copyright © 2011-2022 走看看