iOS类归档,zip压缩。

原创 2015年11月20日 09:47:31

概念

首先简单介绍下类的归档与zip压缩概念:

类的归档:将我们用到object-c对象以文件的形式存储下来,是数据持久化的一种方案。(其他还有 coredata ,sqlite , NSUserDefult) 。

zip压缩:将已存在的文件(图片,语音或者我们归档的文件。。)压缩为zip文件的过程。


归档

这里分为两大类:

1.单个类归档到单个文件,即一个类对应一个文件。

2.多个类归档到一个文件,即多个类对应一个文件。

1.单个类归档到单个文件  

    object-c中有四类对象是可以直接使用NSKeyedArchiverarchivedDataWithRootObject方法将内容写入磁盘的,分别是NSString,NSArray,NSDictionary,NSData

    非以上四种类型的,需要将自定义类实现NSCoding协议并重写encodeWithCoderinitWithCoder两个方法,分别用以编码和反编码。然后在编码时会用NSCoder的子类NSKeyedArchiverNSKeyedUnarchiver分别调用archivedDataWithRootObjectunarchiveObjectWithFile来启动自定义类中重写的那两个方法,类似于回调.

   要将一个自定义的类进行归档,那么类里面的每个属性都必须是可以被归档的,如果是不能归档的类型,我们可以把他转化为NSValue进行归档,然后在读出来的时候转化为响应的类型。


下面看代码:


 // NSString归档
    NSString *tranmitStr = [NSString stringWithFormat:@"我是归档的NSStirng对象"];
    NSString *StringPath = [documentpath stringByAppendingPathComponent:@"string.txt"];
    
    
    if([NSKeyedArchiver archiveRootObject:tranmitStr toFile:StringPath]){
        NSLog(@"归档成功");
    }else{
        NSLog(@"归档失败");
    }

    //NSString 中[tranmitStr writeToFile:@"" atomically:YES]; 这个方法已过期用下面的方法
    //[tranmitStr writeToFile:StringPath atomically:YES encoding:NSStringEncodingConversionAllowLossy error:nil];//writeToFile方法不管用,它能够写一个文件,但是不知道怎么去解档读取里面的文件。<span style="color: rgb(0, 132, 0); font-family: 'Heiti SC Light'; font-size: 11px;">如果用这个方法在接档时候会出现</span><span style="color: rgb(0, 132, 0); font-size: 11px; line-height: normal; font-family: Menlo;">(null)</span><span style="color: rgb(0, 132, 0); font-family: 'Heiti SC Light'; font-size: 11px;">,应该会有里另一种解挡方案与之对应,感兴趣的可以去测试。</span>

   
    // NSData归档
    NSData *tranmitData=[[NSData alloc]init];
    NSString *DataPath = [documentpath stringByAppendingPathComponent:@"data.txt"];
    if([NSKeyedArchiver archiveRootObject:tranmitData toFile:DataPath]){
        NSLog(@"归档成功");
    }else{
        NSLog(@"归档失败");
    }
    
    // NSArray归档
    NSArray *tranmitArray=[[NSArray alloc]initWithObjects:@"a",@"e", nil];
    NSString *ArrayPath = [documentpath stringByAppendingPathComponent:@"array.txt"];
    if([NSKeyedArchiver archiveRootObject:tranmitArray toFile:ArrayPath]){
        NSLog(@"归档成功");
    }else{
        NSLog(@"归档失败");
    }
    // NSDictionary归档
    NSDictionary *tranmitDictionary=[[NSDictionary alloc]initWithObjectsAndKeys:
                                      @"这是NSDictionary当中的内容",@"content",
                                      @"value2",@"key2",
                                      @"value3",@"key3",
                                     nil];
    NSString *DictionaryPath = [documentpath stringByAppendingPathComponent:@"dictionary.txt"];
    if([NSKeyedArchiver archiveRootObject:tranmitDictionary toFile:DictionaryPath]){
        NSLog(@"归档成功");
    }else{
        NSLog(@"归档失败");
    }
    //[tranmitDictionary writeToFile:DictionaryPath atomically:YES];不管用
    
    //自定义类型归档
    CustomBean *bean= [[CustomBean alloc ]init];
    bean.customstr = @"hellow world";
    bean.customint = 12;
   
   // NSData *customBeanData = [NSKeyedArchiver archivedDataWithRootObject:bean];//转化成NSData对象
    NSString *customBeanPath =  [documentpath stringByAppendingPathComponent:@"customBeanPath.txt"];
    if([NSKeyedArchiver archiveRootObject:bean toFile:customBeanPath]){
        NSLog(@"归档成功");
    }else{
        NSLog(@"归档失败");
    }
    
   // [customBeanData writeToFile:customBeanPath atomically:YES];//不能用
    
   //-----------------------单个类解档----------------------------
    
    
    
    NSString *str2 =  [NSKeyedUnarchiver unarchiveObjectWithFile:StringPath];
    NSLog(@"str2 %@:",str2);
    NSArray *array2 = [NSKeyedUnarchiver unarchiveObjectWithFile:ArrayPath];
    NSLog(@" array2 %@:",array2);
    NSDictionary *dic2 =  [NSKeyedUnarchiver unarchiveObjectWithFile:DictionaryPath];
    NSLog(@"dic2 %@:",dic2);
    NSData *data2 = [NSKeyedUnarchiver unarchiveObjectWithFile:DataPath];
    NSLog(@"data2 %@:",data2);
    CustomBean *bean2 = [NSKeyedUnarchiver unarchiveObjectWithFile:customBeanPath];
    NSLog(@"CustomBean  %@:",bean2);
    

CustomBean类是一个键值对的类 ,其实个人认为这个自定义的方式比较鸡肋,我们完全可以用NSDictionary去完成相同的功能。
下面是实现nscoding的方法。
#import <UIKit/UIKit.h>

@interface CustomBean : NSObject<NSCoding>

@property(nonatomic,copy,readwrite) NSString *customstr;
@property(nonatomic,readwrite) int  customint;

@end
#import "CustomBean.h"

@implementation CustomBean

-(void)encodeWithCoder:(NSCoder *)aCoder//要一一对应
{
    [aCoder encodeInt:self.customint forKey:@"customint"];
    [aCoder encodeObject:self.customstr forKey:@"customstr"];
    
}
-(id)initWithCoder:(NSCoder *)aDecoder//和上面对应
{
    if (self=[super init]) {
        self.customint=[aDecoder decodeIntForKey:@"customint"];
        self.customstr=[aDecoder decodeObjectForKey:@"customstr"];
       
    }
    return self;
}

- (NSString *)description{
    NSString *string = [NSString stringWithFormat:@"customstr=%@,customint=%d",self.customstr, self.customint];
    return string;
}
@end


2.多个类归档到一个文件

多个类归档到一个文件的时候需要借助nsmutabledata来完成。

 //-----------------------多个类归档----------------------------
    
    //多个类型归档到一个文件当中需要借助NSMutableData类
    
    NSArray *array = [NSArray arrayWithObjects:@"zhangsan",@"lisi", nil];
    
    NSMutableData *data = [NSMutableData data];//初始化NSMutableData
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];//用NSKeyedArchiver包装一下
    //编码
    [archiver encodeObject:array forKey:@"array"];
    [archiver encodeInt:100 forKey:@"scope"];
    [archiver encodeObject:@"jack" forKey:@"name"];
    
    //完成编码,将上面的归档数据填充到data中,此时data中已经存储了归档对象的数据
    [archiver finishEncoding];
    
    NSString *filePath = [documentpath stringByAppendingPathComponent:@"array.src"];
    //这里调用NSMutableData的writeToFile方法将data写入到本地路径当中。
    BOOL success = [data writeToFile:filePath atomically:YES];
    if(success){
        NSLog(@"多个类归档");
    }
     //-----------------------多个类解档----------------------------
    //读取归档数据
    NSData *data22 = [[NSData alloc] initWithContentsOfFile:filePath];
    //创建解归档对象,对data中的数据进行解归档
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data22];
    //解归档
    NSArray *array22 = [unarchiver decodeObjectForKey:@"array"];
    NSLog(@"多个类解档array22%@",array22);
    
    int value = [unarchiver decodeIntForKey:@"scope"];
    NSLog(@"多个类解档%d",value);
    

压缩

这里需要用到一个第三方的库 ZipArchive 这个库在谷歌的 由于墙的原因我们无法去官网下载。壁纸当初也是从github上下载的。
关于这块可以参照笔者之前写的一个demo  里面有库文件可以拖到自己的工程中去使用 
demo地址:https://github.com/february29/ZIPDecoding

//1.导入 minizip文件夹 ZipArchive.h ZipArchive.mm

//2.导入  libz.tbd

//3.ZipArchive.mm编译选项中,增加-fno-objc-arc

//4.#import "ZipArchive.h"

//5.调用解压,压缩代码 如下所示


//6.time函数报错设置tager ->search path -> always search user path设置为no

// 解压压缩操纵在字线程中做增加用途体验


 ZipArchive* zip = [[ZipArchive alloc] init];
    //压缩后的文件完整路径
    NSString *zipPath;
    zipPath = [documentpath stringByAppendingString:@"/transmit.zip"] ;
    BOOL ret = [zip CreateZipFile2:zipPath];
    
    ret = [zip addFileToZip:StringPath newname:[StringPath lastPathComponent]];
    ret = [zip addFileToZip:DataPath newname:[DataPath lastPathComponent]];
    ret = [zip addFileToZip:ArrayPath newname:[ArrayPath lastPathComponent]];
    ret = [zip addFileToZip:DictionaryPath newname:[DictionaryPath lastPathComponent]];
    

    if( ![zip CloseZipFile2] )
    {
        zipPath = @"";
    }
    
    return zipPath;







用zip归档和压缩

对归档文件采用zip格式进行压缩: $zip  file.zip  [source files/dirs] 举例: $zip file.zip  file 该命令会生成file.zip [r...
  • zhangbest2009
  • zhangbest2009
  • 2012年09月18日 08:39
  • 739

ios自定义对象(或自定义数据类型)归档

*  归档是一种很常用的文件储存方法,几乎任何类型的对象都能够被归档储存(实际上是一种文件保存的形式),步骤如下  1、对象要遵守NSCoding协议    2、实现以下两个方法:   ...
  • xiaonaiping061
  • xiaonaiping061
  • 2015年08月24日 16:16
  • 2238

ios 沙盒 NSCoding 归档 数据存储

NSCoding 跟其他存储方式略有不同,他可以存储对象 对象存储的条件是: 对象需要遵守 NSCoding 协议 存储的时候需要 调用 encodeWithCoder 方法 读取的时候需要调用ini...
  • codywangziham01
  • codywangziham01
  • 2014年05月08日 17:29
  • 6676

iOS-归档模型创建和工具类的封装

数据的存储方式有好多种 plist NSUserDefault CoreData fmdb 归档    这些方式各自有优缺点  如果我们存储数据量小的数据 可以使用归档和 NSUserDefaul...
  • u012701023
  • u012701023
  • 2015年10月16日 08:47
  • 825

iOS存储方式之归档

讲解归档这种iOS本地存储方式,存储单个对象和多个对象的实例
  • Cloudox_
  • Cloudox_
  • 2017年02月12日 15:09
  • 564

IOS 数据持久化只归档与取消归档

以前在学习OC的时候归档这一块老师偷懒没有讲,给我造成了很大的麻烦,总感觉这一块不熟悉,看书的话,这一个知识点都看了好几遍,还是没有掌握,最近我又重新来了一边,对于归档有了自己的一些心得,特来给大家分...
  • HHL110120
  • HHL110120
  • 2014年01月07日 16:08
  • 1702

iOS runtime讲解,并且用runtime动态归档与解档

// //  AppDelegate.m //  Runtime自动归档 // //  Created by CONGAING on 15/7/13. //  Copyright...
  • oQingTing12345
  • oQingTing12345
  • 2015年10月06日 09:14
  • 1714

iOS 数据持久化方式 - 归档 反归档

所谓归档:将复杂对象转化为NSData类型数据(复杂-->归档-->NSData--->WriteToFile) 注意:归档是将对象转化为数据字节,以文件的形式存储在磁盘上, 所谓反归档:将NSD...
  • xuejunrong
  • xuejunrong
  • 2016年06月27日 20:45
  • 3525

ios中 继承对象模型的归档实现

之前项目中使用到了归档的技术,也用到了MJExtension 但是问题是,这个公共库遇到了无法归档的一些问题,让人蛋疼不已,怎么办呢。 对于不能归档的部分,职能手动归档,很是无语。 查找...
  • j_akill
  • j_akill
  • 2015年06月24日 15:00
  • 1259

iOS经典讲解之复杂对象的数据持久化-归档与反归档

自定义类Person.h @interface PersonModel : NSObject /** * 复杂对象最持久化 需要遵守一个协议 */ @property (nonatomic, ...
  • Loving_iOS
  • Loving_iOS
  • 2015年09月15日 23:15
  • 1429
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS类归档,zip压缩。
举报原因:
原因补充:

(最多只允许输入30个字)