iOS数据持久化存储 (1)-- Plist 、归档、NSUserDefaults、NSFileManager 

iOS数据持久化存储(1)

iOS 数据持久化存储方式有很多,博主今天只跟大家分享以下四种方法:

Plist文件、归档、NSUserDefaults 和NSFileManager  


一、Plist文件

在做 iOS 开发时,经常用到plist文件,  那plist文件是什么呢? 它全名是:Property List,属性列表文件,它是一种用来存储串行化后的对象的文件。属性列表文件的扩展名为.plist ,因此通常被称为 plist文件。文件是 json 或 xml格式的。

Plist文件通常用于储存用户设置,也可以用于存储捆绑的信息。

Plist文件可以存放的数据类型:NSStringNSArrayNSDictionaryNSDataNSNumber等。

在开发过程中,有时候需要把程序的一些配置保存下来,或者游戏数据等等。 这时候需要写入 Plist数据写入的plist 文件会生成在对应程序的沙盒目录里


二、归档

归档也叫序列化,是将文件存在硬盘,解档是从硬盘还原。归档和解档的操作正好相反的,但是要注意的是:他们属性的key一定要保持一致。


第1种、使用属性列表进行归档

如果对象是NSString,NSDictionary,NSArray,NSData或者NSNumber,可以使用writeToFile:atomically方法将数据写到文件,注意这种方式是明文

sample:



[java]  view plain copy


1. NSArray *array = @[@"abc",@"123",@23.4];  
2. if ([array writeToFile:@"text.plist" atomically:YES])  
3. {  
4. "success");  
5. }  
6. NSArray *arr2=[NSArray arrayWithContentsOfFile:@"text.plist"];  
7. NSLog(@"%@",arr2);



第2种、NSKeyedArchiver--对象归档,数据会加密

1)、对于NSArray或者NSDictionary sample code:


[java]  view plain copy


1.  /***归档对象****/  
2. "abc",@"123",@23.4];  
3.  NSString *homePath = NSHomeDirectory();  
4. "test.arc"];  
5.    
6. // BOOL success = [NSKeyedArchiver archiveRootObject:array toFile:path];  
7.  BOOL success=[NSKeyedArchiver archiveRootObject:array toFile:path];  
8. if (success) {  
9. "archive success");  
10.  }  
11.    
12. /***解归档****/  
13.  NSArray *array2 =[NSKeyedUnarchiver unarchiveObjectWithFile:path];  
14. SLog(@"%@",array2);


结果:


success

2013-12-28 22:14:25.353 ArchiverDemo1[1206:303] (

abc,

123,

"23.4"

)

2)、如果是其他类型的对象存储到文件,可以利用NSKeyedArchiver类创建带键的档案来完成



[java]  view plain copy


1. NSString *homePath = NSHomeDirectory();  
2. NSString *path = [homePath stringByAppendingPathComponent:@"archiver2.archiv"];  
3. NSMutableData *data = [NSMutableData data];  
4. NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];  
5. NSArray *array = @[@"jack",@"tom"];  
6. [archiver encodeInt:100 forKey:@"age"];  
7. [archiver encodeObject:array forKey:@"names"];  
8. [archiver finishEncoding];  
9. [archiver release];  
10.   
11. BOOL success = [data writeToFile:path atomically:YES];  
12. if (success) {  
13. "archive success");  
14. }  
15.   
16. /***解归档对象**/  
17.   
18. NSData *data2 = [NSData dataWithContentsOfFile:path];  
19. NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data2];  
20. int age = [unArchiver decodeIntForKey:@"age"];  
21. NSArray *names = [unArchiver decodeObjectForKey:@"names"];  
22. [unArchiver release];  
23. NSLog(@"age=%d,names=%@",age,names);




3)、自定义对象进行归档,需要实现归档协议NSCoding两个方法

对属性编码,归档的时候会调用

- (void)encodeWithCoder:(NSCoder *)aCoder
 //对属性解码,解归档调用
 - (id)initWithCoder:(NSCoder *)aDecoder



[java]  view plain copy

1. //对属性编码,归档的时候会调用  
2. - (void)encodeWithCoder:(NSCoder *)aCoder {  
3.     [aCoder encodeInt:_age forKey:AGE];  
4.     [aCoder encodeObject:_name forKey:NAME];  
5.     [aCoder encodeObject:_email forKey:EMAIL];  
6.     [aCoder encodeObject:_password forKey:PASSWORD];  
7.       
8. }  
9.   
10. //对属性解码,解归档调用  
11. - (id)initWithCoder:(NSCoder *)aDecoder {  
12. super init];  
13. if (self != nil) {  
14.         _age = [aDecoder decodeIntForKey:AGE];  
15.         self.name = [aDecoder decodeObjectForKey:NAME];  
16.         self.email = [aDecoder decodeObjectForKey:EMAIL];  
17.         self.password = [aDecoder decodeObjectForKey:PASSWORD];  
18.     }  
19. return self;  
20. }




第3种:NSUserDefaults


sample code:




1. [[NSUserDefaults standardUserDefaults] setObject:authData forKey:@"SinaWeiboAuthData"];  
2. [[NSUserDefaults standardUserDefaults] synchronize];



三、NSUserDefaults 

上面也提到了NSUserDefaults,这里需要补充的是,使用NSUserDefaults存数的数据最终保存在了什么地方。

iOS应用产生的内容,如图像、文件、缓存内容等都必须存储在自己的沙盒内。默认情况下,每个沙盒含有3个文件夹:Documents, Library 和 tmp。Library包含Caches、Preferences目录。

ios文件存档 ios存档大全_文件目录


iTunes备份和恢复的时候会包括此目录
Library:存储程序的默认设置或其它状态信息;

Library/Caches:存放缓存文件,保存应用的持久化数据,用于应用升级或者应用关闭后的数据保存,不会被itunes同步,所以为了减少同步的时间,可以考虑将一些比较大的文件而又不需要备份的文件放到这个目录下。

但不需要持久化,在应用关闭后,该目录下的数据将删除,也可能系统在程序不运行的时候清除。



而使用NSUserDefaults存数的数据最终保存在 Library --> Preferences --> xxx.plist.

ios文件存档 ios存档大全_ios文件存档_02

四、NSFileManager 

NSFileManager中包含了用来查询单词库目录、创建、重命名、删除目录以及获取/设置文件属性的方法(可读性,可编写性等等)。

每个程序都会有它自己的沙盒,通过它你可以阅读/编写文件。写入沙盒的文件在程序的进程中将会保持稳定,即便实在程序更新的情况下。
如下所示,你可以在沙盒中定位文件目录:

//对于错误信息
 NSError *error;
 // 创建文件管理器
 NSFileManager *fileMgr = [NSFileManagerdefaultManager];
 //指向文件目录
 NSString *documentsDirectory= [NSHomeDirectory() 
 stringByAppendingPathComponent:@"Documents"]; //创建一个目录
 [[NSFileManager defaultManager]   createDirectoryAtPath: [NSString stringWithFormat:@"%@/myFolder", NSHomeDirectory()] attributes:nil];


创建一个文件
现在我们已经有了文件目录,我们就能使用这个路径在沙盒中创建一个新文件并编写一段代码:

// File we want to create in the documents directory我们想要创建的文件将会出现在文件目录中
 // Result is: /Documents/file1.txt结果为:/Documents/file1.txt
 NSString *filePath= [documentsDirectory
 stringByAppendingPathComponent:@"file1.txt"];
 //需要写入的字符串
 NSString *str= @"iPhoneDeveloper Tips\nhttp://iPhoneDevelopTips,com";
 //写入文件
 [str writeToFile:filePath atomically:YES 
 encoding:NSUTF8StringEncoding error:&error];
 //显示文件目录的内容
 NSLog(@"Documentsdirectory: %@",
 [fileMgr contentsOfDirectoryAtPath:documentsDirectoryerror:&error]);


我们为想要创建的文件构建一条路径(file1.txt),初始化一个字符串来写入文件,并列出目录。最后一行显示了在我们创建文件之后出现在文件目录下的一个目录列表:

对一个文件重命名
想要重命名一个文件,我们需要把文件移到一个新的路径下。下面的代码创建了我们所期望的目标文件的路径,然后请求移动文件以及在移动之后显示文件目录。

//通过移动该文件对文件重命名
 NSString *filePath2= [documentsDirectory
 stringByAppendingPathComponent:@"file2.txt"];
 //判断是否移动
 if ([fileMgr moveItemAtPath:filePath toPath:filePath2 error:&error] != YES)
 NSLog(@"Unable to move file: %@", [error localizedDescription]);
 //显示文件目录的内容
 NSLog(@"Documentsdirectory: %@", 
 [fileMgr contentsOfDirectoryAtPath:documentsDirectoryerror:&error]);


在移动了文件之后,输出结果应该如下图所示:

删除一个文件
为了使这个技巧完整,让我们再一起看下如何删除一个文件:

//在filePath2中判断是否删除这个文件
 if ([fileMgr removeItemAtPath:filePath2 error:&error] != YES)
 NSLog(@"Unable to delete file: %@", [error localizedDescription]);
 //显示文件目录的内容
 NSLog(@"Documentsdirectory: %@",
 [fileMgr contentsOfDirectoryAtPath:documentsDirectoryerror:&error]);
 一旦文件被删除了,正如你所预料的那样,文件目录就会被自动清空。