属性列表 (自定义的Property List 、NSUserDefaults)
归档 (NSKeyedArchiver)
数据库 (SQLite、Core Data、第三方类库等)
本文只介绍:属性列表和归档
Plist一般用于存储Dictionary、Array、Boolean、Data、Date、Number、String这些类型的数据,但Boolean、Data、Date、Number、String类型的数据一般不直接存入Plist文件中,因为Plist文件有分层的概念,一般用NSDictionary或NSArray作为容器,再把其他数据类型装入,最后把容器存入Plist文件。Plist文件不能直接存储自定义的类,需要进行转化成上述的数据类型,才能存储。
NSDictionary或NSArray使用writeToFile:atomically:方法,会默认存储到Plist文件
// 获取沙盒中documents目录的路径
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
// 拼接路径
NSString *someObjPath = [documentsPath stringByAppendingPathComponent:@"someObj.plist"];
// 要写入文件的数组
NSArray *someObj = @[@"AAA",@"BBB",@999,@'A',@[@{@"name":@"小明"}]];
// 把数组写入plist文件
// 第一个参数是文件名,第二个参数为是否使用辅助文件,如果为YES,则先写入到一个辅助文件,然后辅助文件再重新命名为目标文件,
// 如果为NO,则直接写入到目标文件
[someObj writeToFile:someObjPath atomically:YES];
创建目录 createDirectoryAtPath:
创建文件 createFileAtPath:
删除某个文件 removeItemAtPath:
检查某个文件是否存在 fileExistsAtPath:
检查文件是否可读 isReadableFileAtPath:
是否可写:isWritableFileAtPath:
取得文件属性 fileAttributesAtPath:
改变文件属性changeAttributesAtPath:
从path代表的文件中读取数据:contentsAtPath
移动文件movePath:toPath:handler:
复制文件copyPath:toPath:handler:
// 1. 在沙盒里新建目录,再在目录里新建文件夹
// 创建一个文件管理器
NSFileManager *fileManager = [NSFileManager defaultManager];
// 获取沙盒下的documents路径
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
// 拼接路径
NSString *newFilePath = [documentsPath stringByAppendingPathComponent:@"NewFile"];
// 创建新目录
[fileManager createDirectoryAtPath:newFilePath withIntermediateDirectories:YES attributes:nil error:nil];
// 读写数据一
// 2. 向fileNew.plist写入数据
// 把路径改变到新路径下
[fileManager changeCurrentDirectoryPath:[newFilePath stringByExpandingTildeInPath]];
// 创建fileNew.plist文件
[fileManager createFileAtPath:@"fileNew.plist" contents:nil attributes:nil];
// 写入数据
NSArray *dataArr = @[@[@100,@"study"],@{@"name":@"xiaoming"}];
// 拼接fileNew.plist路径
NSString *dataPath = [newFilePath stringByAppendingPathComponent:@"fileNew.plist"];
// 把数组写入fileNew.plist
[dataArr writeToFile:dataPath atomically:YES];
// 3. 读取fileNew.plist数据
NSArray *arrData = [NSArray arrayWithContentsOfFile:dataPath];
NSLog(@"%@",arrData);
// 读写数据二
// 使用NSMutableData存储数据要记住存储的顺序,读取数据时要要根据那个顺序计算每个数据所处的位置
// 2. 向fileName文件写入数据
// 待写入的数据
NSString *dataStr = @"New Friend";
int dataInt = 666;
float dataFloat = 3.14159f;
// 拼接存储数据的路径
NSString *dataPath2 = [newFilePath stringByAppendingPathComponent:@"fileName"];
//创建数据缓冲
NSMutableData *writerData = [[NSMutableData alloc] init];
//将字符串添加到缓冲中
[writerData appendData:[dataStr dataUsingEncoding:NSUTF8StringEncoding]];
//将其他数据添加到缓冲中
[writerData appendBytes:&dataInt length:sizeof(dataInt)];
[writerData appendBytes:&dataFloat length:sizeof(dataFloat)];
//将缓冲的数据写入到文件中
[writerData writeToFile:dataPath2 atomically:YES];
// 3. 读取数据:
// 读取fileName文件中的数据
NSData *readerData = [NSData dataWithContentsOfFile:dataPath2];
// 计算dataStr在dataStr的区间,并获取字
dataStr = [[NSString alloc] initWithData:[readerData subdataWithRange:NSMakeRange(0, [dataStr length])]
encoding:NSUTF8StringEncoding];
// 计算dataInt在dataStr的区间,并获取
[readerData getBytes:&dataInt range:NSMakeRange([dataStr length], sizeof(dataInt))];
// 计算dataFloat在dataStr的区间,并获取
[readerData getBytes:&dataFloat range:NSMakeRange([dataStr length] + sizeof(dataInt), sizeof(dataFloat))];
NSLog(@"dataStr:%@ dataInt:%d dataFloat:%f", dataStr,dataInt,dataFloat);
// 删除fileName文件
[fileManager removeItemAtPath:@"fileName" error:nil];
// 删除一个目录:
// currentDirectoryPath:当前目录
NSLog(@"%@",fileManager.currentDirectoryPath);
[fileManager removeItemAtPath:fileManager.currentDirectoryPath error:nil];
偏好设置的本质还是plist文件存储,相对于Plist文件存储来讲存储数据更快捷,不需要获取全路径。
偏好设置用来保存应用程序设置和属性、用户保存的数据,当用户再次打开程序或开机后这些数据仍然存在。
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setValue:@"小明" forKey:@"name"];
[userDefaults setValue:@"男" forKey:@"sex"];
[userDefaults setValue:@"学生" forKey:@"work"];
// 写入磁盘
[userDefaults synchronize];
NSLog(@"%@",[userDefaults objectForKey:@"name"]);
NSLog(@"%@",[userDefaults objectForKey:@"sex"]);
NSLog(@"%@",[userDefaults objectForKey:@"work"]);
缺点:在归档的形式来保存数据,只能一次性归档保存以及一次性解压,所以只能针对小量数据。而且对数据操作比较笨拙,即如果想改动数据的某一小部分,还是需要解压整个数据或者归档整个数据。
归档方式有以下三种:
a. 对Foundation框架中对象进行归档
b. 对自定义的内容进行归档
c. 对自定义的对象进行归档
// 获取文件路径
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
// 拼接路径
NSString *dataPath = [documentsPath stringByAppendingPathComponent:@"NewData.data"];
// 待归档的数据
NSArray *dataArr = @[@"天天",@"编程"];
// 归档
if ([NSKeyedArchiver archiveRootObject:dataArr toFile:dataPath]) {
NSLog(@"Archiver success !");
}
// 解档
NSArray *data = [NSKeyedUnarchiver unarchiveObjectWithFile:dataPath];
NSLog(@"%@%@",data[0],data[1]);
// 获取文件路径
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
// 拼接路径
NSString *dataPath = [documentsPath stringByAppendingPathComponent:@"NewData.data"];
// 创建存储数据的NSData对象
NSMutableData *dataM = [NSMutableData data];
// 创建归档对象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:dataM];
// 添加归档内容
[archiver encodeObject:@"小明" forKey:@"name"];
[archiver encodeObject:@"男" forKey:@"sex"];
[archiver encodeInteger:19 forKey:@"age"];
// 完成归档内容
[archiver finishEncoding];
// 写入磁盘
if ([dataM writeToFile:dataPath atomically:YES]) {
NSLog(@"Archiver success !");
}
// 解档
// 获取数据
NSData *data = [NSData dataWithContentsOfFile:dataPath];
// 创建解档对象
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
// 解档
NSString *name = [unarchiver decodeObjectForKey:@"name"];
NSString *sex = [unarchiver decodeObjectForKey:@"sex"];
NSInteger age = [unarchiver decodeIntForKey:@"age"];
NSLog(@"%@ %@ %ld",name,sex,age);
---------- Person.h 文件
#import
@interface Person : NSObject <NSCoding>
@property (nonatomic,strong) NSString *name;
@property (nonatomic,strong) NSString *sex;
@property (nonatomic,assign) NSInteger age;
@end
---------- Person.m 文件
#import "Person.h"
@implementation Person
// 归档
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.sex forKey:@"sex"];
[aCoder encodeInteger:self.age forKey:@"age"];
}
// 解档
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.sex = [aDecoder decodeObjectForKey:@"sex"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
}
return self;
}
@end
---------- 对Penson对象进行归档与解档
// 获取Documents的路径
NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
// 拼接路径
NSString *path = [documentPath stringByAppendingPathComponent:@"person.data"];
//
Person *per = [[Person alloc] init];
per.name = @"xiaoming";
per.sex = @"男";
per.age = 20;
// 归档
[NSKeyedArchiver archiveRootObject:per toFile:path];
// 解档
Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
NSLog(@"%@",person.sex);