标签:
/***** 该文一共总结了以下六种文件操作 1.NSKeyedArchiver、 2.对类对象进行归档 <NSCoder>协议 3.文件管理类 NSFileManger 4.对文件操作 plist 5.NSUserDefault 单例类 6.Json解析********/
/*
1.如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,就可以使用writeToFile:atomically:方法直接将对象写到属性列表文件中
将一个NSDictionary对象归档到一个plist属性列表中
// 将数据封装成字典------------------------------------------------
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"母鸡" forKey:@"name"];
[dict setObject:@"15013141314" forKey:@"phone"];
[dict setObject:@"27" forKey:@"age"];
// 将字典持久化到Documents/stu.plist文件中
[dict writeToFile:path atomically:YES];
读取属性列表,恢复NSDictionary对象-------------------------------------
// 读取Documents/stu.plist的内容,实例化NSDictionary
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(@"name:%@", [dict objectForKey:@"name"]);
NSLog(@"phone:%@", [dict objectForKey:@"phone"]);
NSLog(@"age:%@", [dict objectForKey:@"age"]);
2.注意:UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还 没有写入磁盘应用程序就终止了。出现以上问题,可以通过调用synchornize方法强制写入
[defaults synchornize];
3.如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,可以直接用NSKeyedArchiver进行归档和恢复
4.不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的对象才可以
5.NSCoding协议有2个方法:
encodeWithCoder:
每次归档对象时,都会调用这个方法。一般在这个方法里面指定如何归档对象中的每个实例变量,可以使用encodeObject:forKey:方法归档实例变量
initWithCoder:
每次从文件中恢复(解码)对象时,都会调用这个方法。一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey方法解码实例变量
6.如果父类也遵守了NSCoding协议,请注意:
应该在encodeWithCoder:方法中加上一句
[super encodeWithCode:encode];
确保继承的实例变量也能被编码,即也能被归档
应该在initWithCoder:方法中加上一句
self = [super initWithCoder:decoder];
确保继承的实例变量也能被解码,即也能被恢复
7.使用archiveRootObject:toFile:方法可以将一个对象直接写入到一个文件中,但有时候可能想将多个对象写入到同一个文件中,那么就要使用NSData来进行归档对象
NSData可以为一些数据提供临时存储空间,以便随后写入文件,或者存放从磁盘读取的文件内容。可以使用[NSMutableData data]创建可变数据空间
*/
#pragma mark 一、 NSKeyedArchiver=========================================================
#pragma mark NSKeyedArchiver 第一种方式:存储一种数据。============================
/*
【注】归档的文件都是经过简单加密的,打不开,也是不允许打开的。
第一种写法
对象--文件
创建了一个数组,初始化了一些数据
NSArray* array = [[NSArray alloc]initWithObjects:@"zhangsan",@"lisi",@"wanger",@"xiaoming", nil];
先指定要保存的文件名称以及路径
NSHomeDirectory()就是当前系统的home路径
stringByAppendingPathComponent 添加一个文件,文件名是:file
文件类型可以不写,文件名称和后缀随便
归档文件路径
NSString* filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"file.txt"];
NSKeyedArchiver 这个类是用来归档的类
返回值代表归档是否成功
【注】如果对同一个路径下的同一个文件进行归档操作,就会覆盖掉旧的。
BOOL isSuccess = [NSKeyedArchiver archiveRootObject:array toFile:filePath];
if (isSuccess == YES) {
NSLog(@"文件保存成功");
}
解归档-----------------------------
NSArray* Arr = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
NSLog(@"取出的数据是:%@",Arr);
*/
#pragma mark NSKeyedArchiver 第二种方式:存储并行数据(存储多种数据)============================
/*
第二种写法:
NSArray* array1 = @[@"one",@"two",@"three"];
NSDictionary* dic = @{@"key":@"value"};
NSString* str = @"我是中国人,我爱中国";
NSData 数据流类
用来存储复杂的数据,把复杂的数据转成数据流格式,可以方便进行存储和传输。
例如:图片、大文件
断点续传,假如图片有20M大,
发邮件:添加附件
NSMutableData* data = [[NSMutableData alloc]init];
initForWritingWithMutableData 指定要写入的数据流文件
NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
编码数据,参数一:要准备编码的数据;参数二:编码数据的key,key随便写
[archiver encodeObject:array1 forKey:@"array1"];
[archiver encodeObject:dic forKey:@"dic"];
[archiver encodeObject:str forKey:@"str"];
编码完成
[archiver finishEncoding];
指定文件路径
NSString* filePath2 = [NSHomeDirectory() stringByAppendingPathComponent:@"file2"];
写入文件
[data writeToFile:filePath2 atomically:YES];
下部分解档-------------------------------------------------
先把路径下的文件读入数据流中
NSMutableData* fileData = [[NSMutableData alloc]initWithContentsOfFile:filePath];
把数据流文件读入到了 解归档中
NSKeyedUnarchiver* unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:fileData];
进行解归档
NSArray* UnArray = [unArchiver decodeObjectForKey:@"array1"];
NSDictionary* UnDic = [unArchiver decodeObjectForKey:@"dic"];
NSString* UnStr = [unArchiver decodeObjectForKey:@"str"];
打印
NSLog(@"%@\n%@\n%@\n",UnArray,UnDic,UnStr);
*/
#pragma mark 二、 对类对象进行归档 <NSCoder>协议=========================================================
/*
归档方式:对类对象进行归档
1.先在类的头文件中实现<NSCoding>协议
2.在.m中重新编码和解码协议。
【注】forKey:是字符串;编码方法和解码方法字符串要一致
重新initWithCoder 解码方法
-(id)initWithCoder:(NSCoder *)aDecoder
{
NSLog(@"我是解码方法,我负责解码");
self = [super init];
if (self) {
_name = [aDecoder decodeObjectForKey:@"name"];
_phone = [aDecoder decodeObjectForKey:@"phone"];
_address = [aDecoder decodeObjectForKey:@"address"];
}
return self;
}
重新编码方法
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeObject:_phone forKey:@"phone"];
[aCoder encodeObject:_address forKey:@"address"];
}
*/
#pragma mark 三、文件管理类 NSFileManger=====================================================================
/*
1.文件路径
根路径
NSString* homePath = NSHomeDirectory();
oc中有三个目录是可以操作的:
1.Documents//文稿目录
2.tmp//临时目录:程序退出的时候,临时目录内容可能会被情况
3.library--->Cache//缓存目录//app目录下
获取Documents 目录
写法一
NSString* Documents = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
写法二
NSString* Documents1 = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDirectory, YES) objectAtIndex:0];
获取应用程序的主目录
NSString* userName = NSUserName();
NSString* rootPath = NSHomeDirectoryForUser(userName);
NSLog(@"app root path:%@",rootPath);
获取cache目录
NSString* cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSLog(@"cache :%@",cachePath);
获取tmp目录
NSString* tmpPath = NSTemporaryDirectory();
NSLog(@"tmp:%@",tmpPath);
2.创建目录和文件
获取根目录
NSString* homePath = NSHomeDirectory();
创建了一个文件管理器
NSFileManager* fileMgr = [NSFileManager defaultManager];
拼接出想要创建的文件路径
NSString* filePath = [NSString stringWithFormat:@"%@/myFolder",homePath];
创建文件目录
第一个参数传入想要创建的文件目录,第二个参数指导是否创建不存在的文件夹,yes代表创建
BOOL isOk = [fileMgr createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
if (isOk) {
NSLog(@"创建文件目录成功");
}
NSString* string = @"我爱记歌词";
把内容写入到指定路径下的指定文件中
BOOL isWriteOk = [string writeToFile:[NSString stringWithFormat:@"%@/1.txt",filePath] atomically:YES encoding:NSUTF8StringEncoding error:nil];
if (isWriteOk) {
NSLog(@"写入文件成功");
}
数组保存
NSArray* array = @[@"我是一",@"我是三",@"我是周7"];
BOOL isWriteOK1 = [array writeToFile:[NSString stringWithFormat:@"%@/2.txt",filePath] atomically:YES];
if (isWriteOK1) {
NSLog(@"数组写入文件成功");
}
字典保存
NSDictionary* dic = @{@"key":@"value"};
BOOL isWriteOK2 = [dic writeToFile:[NSString stringWithFormat:@"%@/3.txt",filePath] atomically:YES];
if (isWriteOK2) {
NSLog(@"字典写入文件成功");
}
2.对文件进行重命名
获取根目录
NSString* homePath = NSHomeDirectory();
创建了一个文件管理器
NSFileManager* fileMgr = [NSFileManager defaultManager];
拼接出想要创建的文件路径
NSString* filePath = [NSString stringWithFormat:@"%@/myFolder/1.txt",homePath];
[fileMgr moveItemAtPath:filePath toPath:[NSString stringWithFormat:@"%@/ai.txt",homePath] error:nil];
3.删除一个文件
声明了一个错误信息的对象
NSError* error;
获取根目录
NSString* homePath = NSHomeDirectory();
创建了一个文件管理器
NSFileManager* fileMgr = [NSFileManager defaultManager];
拼接出想要创建的文件路径
NSString* filePath = [NSString stringWithFormat:@"%@/myFolder/3.txt",homePath];
删除文件
如果方法执行返回是NO,error会保存错误信息,如果方法执行返回是YES,error = nil
BOOL isok = [fileMgr removeItemAtPath:filePath error:&error];
if (isok) {
NSLog(@"删除文件成功");
}
else
{
NSLog(@"删除文件失败");
打印错误信息
NSLog(@"%@",error.localizedDescription);
}
Δ【扩展】NSError类,是一个错误信息类
删除文件
如果方法执行返回是NO,error会保存错误信息,如果方法执行返回是YES,error = nil
BOOL isok = [fileMgr removeItemAtPath:filePath error:&error];
?4.删除目录下的所有文件
获取根目录
NSString* homePath = NSHomeDirectory();
创建了一个文件管理器
NSFileManager* fileMgr = [NSFileManager defaultManager];
拼接出想要创建的文件路径
NSString* filePath = [NSString stringWithFormat:@"%@/myFolder/3.txt",homePath];
如果删除的目录中不带具体的文件,则删除的是整个目录
[fileMgr removeItemAtPath:[NSString stringWithFormat:@"%@/myFolder/",homePath] error:nil];
5.获取目录下的所有文件
获取根目录
NSString* homePath = NSHomeDirectory();
创建了一个文件管理器
NSFileManager* fileMgr = [NSFileManager defaultManager];
拼接出想要创建的文件路径
NSString* filePath = [NSString stringWithFormat:@"%@/myFolder/",homePath];
获取当前目录下的所有文件,包括隐藏文件
NSArray* allFile = [fileMgr contentsOfDirectoryAtPath:filePath error:nil];
NSLog(@"%@",allFile);
获取当前目录以及子目录的所有文件
NSArray* subAllFile = [fileMgr subpathsOfDirectoryAtPath:filePath error:nil];
6.文件的属性
获取根目录
NSString* homePath = NSHomeDirectory();
创建了一个文件管理器
NSFileManager* fileMgr = [NSFileManager defaultManager];
拼接出想要创建的文件路径
NSString* filePath = [NSString stringWithFormat:@"%@/myFolder/3.txt",homePath];
NSDictionary* fileAttribute = [fileMgr fileAttributesAtPath:filePath traverseLink:YES];
获取文件的属性
NSData* data = [fileAttribute objectForKey:NSFileModificationDate];
NSLog(@"文件的创建日期:%@",data);
文件占多少字节
NSNumber * number = [fileAttribute objectForKey:NSFileSize];
NSLog(@"文件的大小:%@",number);
判断文件是否存在
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isExist = [fileManager fileExistsAtPath:filePath];
*/
#pragma mark 四、对文件操作 plist=======================================================
/*
一、plist文件的操作=====================================
.plist文件是一个属性字典数组的一个文件;
.plist文件可以用来存储:字典、数组、字符串等对象数据,可以混搭存储
【注】iOS开发中,plist文件一般用于app的配置信息
【注】ios开发工程中,允许多个plist文件共存。
【注】plist文件用来存储小数据量的数据
优点:可视化以及可编辑性非常方便
1.创建plist文件----------------------------------------------------------------
NSMutableDictionary* dic = [[NSMutableDictionary alloc]init];
[dic setObject:@"张三" forKey:@"name"];
[dic setObject:@"李四9999" forKey:@"name1"];
[dic setObject:@"王二" forKey:@"name2"];
【注】如果key相同,数据会被冲掉
[dic setObject:@"zhangsan" forKey:@"name"];
把数据写入文件
[dic writeToFile:Path atomically:YES];
atomically
atomically: 参数意思,原子操作
如果atomically的参数是yes,程序会把数据先备份一下,等全部写入到了缓存中再一次性写入文件
如果atomically的参数是no,程序会直接把数据写入缓存
2.创建一种多键值的plist文件---------------------------------------------------------
NSMutableDictionary* plugin1 = [[NSMutableDictionary alloc]init];
[plugin1 setObject:@"张三1" forKey:@"name1"];
[plugin1 setObject:@"李四" forKey:@"name2"];
NSMutableDictionary* plugin2 = [[NSMutableDictionary alloc]init];
[plugin2 setObject:@"王二" forKey:@"name1"];
[plugin2 setObject:@"赵五" forKey:@"name2"];
NSMutableDictionary* listDic = [[NSMutableDictionary alloc]init];
[listDic setObject:plugin1 forKey:@"初中一班"];
[listDic setObject:plugin2 forKey:@"初中二班"];
[listDic setObject:@"一哥" forKey:@"name"];
[listDic writeToFile:Path atomically:YES];
3.对某一个属性进行修改----------------------------------------------------------------
?首先应该先读取当前plist文件,读出所有数据
读取指定目录下的文件内容
NSMutableDictionary* appList = [[NSMutableDictionary alloc]initWithContentsOfFile:Path];
[appList setObject:@"二哥" forKey:@"name"];
NSMutableDictionary* chu1 = [appList objectForKey:@"初中一班"];
NSString* name1 = [chu1 objectForKey:@"name1"];
[[appList objectForKey:@"初中一班"] objectForKey:@"name1"];
通过取出的内容,重新组合一个新的内容,把新的内容数据重新存入plist中
[chu1 setObject:@"qianfeng" forKey:@"name1"];
[appList setObject:chu1 forKey:@"初中一班"];
[appList writeToFile:Path atomically:YES];
【总结】
1.plist文件操作其实就是一个根目录是字典,内部数据各种嵌套操作。
2.如果想要修改plist中的某个字段内容,一层一层去找,找到后一层一层封装回来,重新写入文件。(文件的覆盖过程)
3.plist不允许出现key值重名,如果重名,会把之前的名称下的值给冲掉。
*/
#pragma mark 五、NSUserDefault 单例类==========================================================
/*
一.NSUserDefault 对文件进行存储的类================================
0.NSUserDefaults 是一个单例类,调用单例方法
1. NSUserDefault是一个本地数据存储类,可以存储小数据量的信息。
2. NSUserDefault 在iOS中常用来存储用户的个人信息,以及登陆注册信息。
【注】1.NSUserDefault 可以存储的数据类型有:NSNumber(NSInterger、flost、double),NSDictionary,NSArray、Bool,NSString这些数据类型
2.到目前为止,所学的归档、写文件、NSUserDefault都是存储小数据量信息的类,他们可以存储大数据量但是会出现性能问题。存储大数据量信息用【数据库】
【数据库】
1.SQlite 底层的数据,需要自己手动去创建数据库文件(db),并且需要手动去书写sqlite 语句;
2.【core data】是苹果公司提供的一种数据库存储、查询、修改、删除等操作一种解决方案;core data数据库其实就是一个对sqlit3进行封装的类库。
3.第三方数据库。
例:
文件的存储-----------------------------------------------------------------------------
NSUserDefaults* defaul = [NSUserDefaults standardUserDefaults];
NSArray* classInfo = @[@"初中一班",@"66个同学",@"平均成绩99.98",@{@"key":@"value"}];
设置key和value
[defaul setObject:classInfo forKey:@"clss_Info"]; // 数组
[defaul setObject:@"15588605664" forKey:@"userName"];
[defaul setObject:@"123456" forKey:@"password"];
[defaul setObject:@"YES" forKey:@"status"]; // YES 就是1 NO 就是 0
[defaul setBool:YES forKey:@"status"];
[defaul setInteger:1 forKey:@"int"];
[defaul setObject:[NSNumber numberWithBool:YES] forKey:@"status1"];
[defaul setFloat:0.15 forKey:@"float"];
把设置的内容存储到程序给NSUserDefaults所分配的空间文件中
系统会把NSUserDefaults存储的文件都放到app的一个指定的目录,其实这个目录就是在根目录的library目录下一个新的目录下
[defaul synchronize];
[注]synchronize 一定要写这个方法,可以确保数据万无一失,如果不写这个方法,可能会存在数据没有保存成功的情况,例如在多线程中进行数据保存;
读取文件的方式-----------------------------------------------------------------------------
NSString* userName = [defaul objectForKey:@"userName"];
NSString* pwd = [defaul objectForKey:@"password"];
只要是牵扯到key和value的,那么存储的时候key怎么写,取的时候,key必须怎么写
只要是牵扯到key和value的,那么存储的key如果一样,肯定会发生覆盖
NSArray* ClassAllInfo = [defaul objectForKey:@"clss_Info"];
BOOL isok = [defaul objectForKey:@"status"];
float f1 = [defaul floatForKey:@"float"];
NSInteger i = [defaul integerForKey:@"int"];
BOOL b = [defaul boolForKey:@"status"];
NSLog(@"%@ %@",userName,pwd);
【扩展】-----------------------------------------------------------------------
1.编程中文件的命名最好不要有中文、空格、特殊符号(因为计算机会对中文或者空格或者特殊符号进行转义)
2.文件和内存数据之间的转换关系
cpu(计算机处理数据大脑)所有的数据都是按照cpu的指令去调度执行
本地文件——>内存 (读的过程)
内存 ——>本地文件 (写的过程)
【注】代码中定义的变量或者对象变量,这些变量的内容都是在内存中存储运算。如果想把一些有用的信息永久保留,就需要把信息保存到文件中。
(1)内存中的数据,都是一些临时数据,当计算机发生意外情况(断电),内存中的数据都会消失;
(2)把内存中的输入写入到文件中,就可以永久保存,只要文件没有被删除。
*/
#pragma mark 六、Json解析============================================================
/*
一、json格式解析
1.json
2.xml
【比较】xml格式出现的比json格式早,xml就是表单(表格)(<body>name</body>),xml最致命的缺点就是可阅读性不高,导致程序员解析比较麻烦。xml优点是应用到大数据量。但是,随着移动端的兴起,json这种格式也开始流行。逐渐成为ios平台和安卓平台app端获取数据一种格式。json格式优点:格式清晰,应用于小数据量的获取。
【注】可以利用http://www.bejson.com/ 对json格式进行校验并规整。
协议很多种:http ftp mail file socket xmpp
url格式: 协议://域名(ip地址):端口/路径 ?参数列表(以&符间隔每个参数)
例:----------------------------------------------------------------------------------------
#import <Foundation/Foundation.h>
#import "MyModel.h" //该类中有content/modelId/user(通过UserModel.h创建user,即属于组合关系)属性(成员变量)
#import "UserModel.h"//该类中有avatar_updataed_at/created_at/last_debice属性(成员变量)
#define PATH @"http://m2.qiushibaike.com/article/list/latest?page=1&count=30&rqcnt=21&r=a1ef5f561429944164282"
把字符串类型转成NSURL类型,转换的过程,字符串内容不变
NSURL *url = [NSURL URLWithString:PATH];
//initWithContentsOfFile:读本地文件
//NSData *data1 = [[NSData alloc] initWithContentsOfFile:@""];
通过url获取数据 NSData:是数据流格式
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
NSError *error = nil;
它(NSJSONSerialization)为苹果系统自带解析,提供的一个解析json数据格式的一个类.
此方法是把data解析成NSDictionary 操作读取可变内容
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
if (error) {
NSLog(@"解析失败");
exit(-1);
}
NSArray *array = [dic objectForKey:@"items"];
创建一个数组,用来存储数据模型
NSMutableArray *dataArray = [[NSMutableArray alloc] init];
遍历items 这个节点下的所有数据
for (int i = 0; i < array.count; i++) {
创建一个myModel 模型
ios中把数据赋给一个对象的属性变量,而这个对象的作用就是为了用来装数据的,那么这个类就称为模型类
MyModel *myModel = [[MyModel alloc] init];
NSDictionary *dicItem = array[i];
这里的key一定要对应url返回来字段值
myModel.content = [dicItem objectForKey:@"content"];
myModel.modelId = [dicItem objectForKey:@"id"];
isMemberofClass 是用来判断是否属于哪个类的成员
可以用isMemberofClass:[NSNull class] 来判断是否为空
if (![[dicItem objectForKey:@"user"] isMemberOfClass:[NSNull class]] ) {
NSDictionary *userDic = [dicItem objectForKey:@"user"];
UserModel *userModel = [[UserModel alloc] init];
userModel.avatar_updated_at = [userDic objectForKey:@"avatar_updated_at"];
userModel.created_at = [userDic objectForKey:@"created_at"];
userModel.last_device = [userDic objectForKey:@"last_device"];
myModel.user = userModel; //通过组合关系进行赋值,让一个类拥有另外一个类的成员变量
}
[dataArray addObject:myModel];
}
从存放model模型的数组中打印数据信息
for (MyModel *myModel in dataArray) {
NSLog(@"content:%@,modelId:%@",myModel.content,myModel.modelId);
UserModel *userModel = myModel.user;
NSLog(@"更新时间:%@,创建时间:%@,最终设备:%@",userModel.avatar_updated_at,userModel.created_at,userModel.last_device);
}
}
Json提取信息练习题==================================================================================
http://www.bejson.com/jshtml_format/
http://m2.qiushibaike.com/article/list/latest?page=1&count=30&rqcnt=21&r=a1ef5f561429944164282
//1.分类接口
http://online.dongting.com/module/rank?page=1&utdid=VPKhKyoz9h4DANpyKlAtL6Pe&size=100
//2.娱乐接口
//3.旅游折扣
4.url://娱乐接口 题目要求:请用数据模型存储title、intro、alt
5.http://online.dongting.com/module/rank?page=1&utdid=VPKhKyoz9h4DANpyKlAtL6Pe&size=100
取出数据中的_id,name,desc,time; 和singer_name 、song_name;通过模型存入数组中,然后通过写文件的方式写入到根目录下的/lrcInfo/1.txt文件中,如果文件不存在请先创建,如果文件存在,则删除文件拷贝到跟目录中,文件重命名为:2.txt
6.取出如下url中的所有数据,写入plist文件
*/
标签:
原文地址:http://www.cnblogs.com/GJ-ios/p/5323302.html