iOS类归档,zip压缩。
2015-11-20 09:47
411 查看
概念
首先简单介绍下类的归档与zip压缩概念:类的归档:将我们用到object-c对象以文件的形式存储下来,是数据持久化的一种方案。(其他还有 coredata ,sqlite , NSUserDefult) 。
zip压缩:将已存在的文件(图片,语音或者我们归档的文件。。)压缩为zip文件的过程。
归档
这里分为两大类:1.单个类归档到单个文件,即一个类对应一个文件。
2.多个类归档到一个文件,即多个类对应一个文件。
1.单个类归档到单个文件
object-c中有四类对象是可以直接使用NSKeyedArchiver的archivedDataWithRootObject方法将内容写入磁盘的,分别是NSString,NSArray,NSDictionary,NSData。非以上四种类型的,需要将自定义类实现NSCoding协议并重写encodeWithCoder和initWithCoder两个方法,分别用以编码和反编码。然后在编码时会用NSCoder的子类NSKeyedArchiver和NSKeyedUnarchiver分别调用archivedDataWithRootObject和unarchiveObjectWithFile来启动自定义类中重写的那两个方法,类似于回调.
要将一个自定义的类进行归档,那么类里面的每个属性都必须是可以被归档的,如果是不能归档的类型,我们可以把他转化为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;
相关文章推荐
- 详解 iOS 上机题!附个人见解
- 【译】详细讲述iOS自定义转场
- iOS/OS X内存管理(二):借助工具解决内存问题
- 17个提升iOS开发效率的必用工具
- iOS 快速集成ShareSDK实现分享功能
- #if 0 ... #endif的真实用途
- iOS中几种数据持久化方案:我要永远地记住你!
- iOS新闻客户端开发教程6-二级栏目导航条
- 【读书笔记】】iOS-数据交换格式
- 【读书笔记】】iOS-数据交换格式
- iOS中date和string的相互转换
- iOS知识点系统分类
- iOS中 自定义系统相机 作者:韩俊强
- iOS中 自定义系统相机 作者:韩俊强
- Kiwi,BDD行为测试框架--iOS攻城狮进阶必备技能
- Kiwi,BDD行为测试框架--iOS攻城狮进阶必备技能
- 【内容转载】iOS开发----Xcode7升级之后插件无法使用与不小心点击Skipbundle的解决办法
- iOS_正则表达式
- 蓝懿 iOS 技术交流和心得分享 11.19
- IOS 百度地图使用问题(动画同时执行)