您的位置:首页 > 移动开发 > IOS开发

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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: