UI:归档、反归档、数据持久化
支持的文件读写类型:字符串、数组、字典、NSdata (可变的、不可变的。共有8个类)
对于数组、字典在写入文件时,其中的元素也必须是以上四种类型之一。
支持的数据类型有限、且简单
写入文件:
字符串写入文件:
writeToFile: atomically: encoding: error
读取字符串:
stringWithContentsOfFile:Encoding:error
数组的写入文件
writeToFile: atomically:
数组的读取:
arrayWithContentsOfFile:
字典写入文件:
writeToFile: atomically:
字典的读取:
dictionaryWithContentsOfFile:
代码:
#pragma mark (.h文件)-------------------------------------------------------------------------------------------------------- #pragma mark (.m文件)-------------------------------------------------------------------------------------------------------- #import "AppDelegate.h" @interface AppDelegate () @end @implementation AppDelegate -(void)dealloc{ [_window release]; [super dealloc]; } /* Documents 对于一款应用,想长久存储的数据,都放在这个文件夹下面,但是不能预留的太多(一般是80M,如果过多,在上线的时候容易被拒绝) Library: Library/Preference 存放用户的一些偏好设置,如用户名,密码,是否是第一次启动 Library/Caches 缓存文件夹,对于这个文件夹,通过应用去下载的视频、音频、小说、图片 tmp: 文件夹是一个临时的问价夹,一般是存放我们应用程序所下载的压缩包,比如我们下载的Zip压缩包. 上面的三个文件夹是系统自动生成的三个文件夹,用户没有权限去删除。但是我们可以自己创建一个自己能够清除缓存的应用,我们可以删除自己创建的文件夹。 */ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // // Override point for customization after application launch. // self.window.backgroundColor = [UIColor whiteColor]; // [self.window makeKeyAndVisible]; /* //获取沙盒文件夹的路径 NSString * homePath = NSHomeDirectory(); NSLog(@"%@",homePath); //获取应用程序的包 NSString * boundlePath = [[NSBundle mainBundle] bundlePath]; NSLog(@"boundlePath:_>%@",boundlePath); //获取沙盒文件夹的 Documents 文件夹 //第一个参数:对应搜索的文件夹,就是要查找的文件夹 //第二个参数:是要查找的文件夹所在的范围,用户域中去查找 //第三个参数:设置是否显示一个详细的路径。如果是就给一个 YES //之前用于 PC (OS X电脑)端,可以同时有多个用户,所以我们获取的是所有的用户的文件路径。而 IOS 平台下,用户只有一个,所以在这里我们获取的路径,就只有一个。 NSString * documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSLog(@"documentsPath_>%@",documentsPath); //获取其他的文件夹路径 //获取 Library 路径 它有两个子文件夹:Caches Preferences NSString * LibaryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)firstObject]; NSLog(@"获取 Library 路径_>%@",LibaryPath); //获取沙盒中 Library 中的 Caches 文件夹路径 NSString * caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]; NSLog(@"获取沙盒中 Library 中的 Caches 文件夹路径_>%@",caches); //获取包中的资源路径 NSString * filePath = [[NSBundle mainBundle] pathForResource:@"某文件名字" ofType:@"文件类型"]; NSLog(@"获取包中的资源路径_>%@",filePath); //获取沙盒中 Preferences 文件夹路径 //获取 tmp 文件夹 NSString * tmpPath = NSTemporaryDirectory(); NSLog(@"获取 tmp 文件夹_>%@",tmpPath); //NSUserDefaults 操作的是沙盒文件夹下的 Library 文件夹的 Preference 文件夹 NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; //存储用户名 [defaults setObject:@"User" forKey:@"UserName"]; [defaults setObject:@"pasword" forKey:@"PasWord"]; [defaults setBool:YES forKey:@"FirstLunch"];//用来存储第一次启动,系统会自动的走一个保存的方法 [defaults synchronize];//如果,不写这句,过一段时间,程序也会走保存数据,这里就是防止程序突然中断,这里是立即保存数据(简单的不复杂的数据) */ return YES; }
#pragma mark (ArchiverController.h文件)-------------------------------------------------------------------------------------------------------- #import <UIKit/UIKit.h> @interface ArchiverController : UIViewController @end #pragma mark (ArchiverController.m文件)-------------------------------------------------------------------------------------------------------- #import "ArchiverController.h" #import "Person.h" /* //关联归档文件类 //归档也叫存入文件 序列话 //反归档就是取出文件 一般都是针对一些自定义的复杂的类,如 MODEL类 一要遵守 NSCoding 协议 二要重写两个协议方法 */ @interface ArchiverController () @end @implementation ArchiverController - (void)viewDidLoad { [super viewDidLoad]; //归档 } //归档 - (IBAction)archiver:(id)sender { Person * per = [[Person alloc]init]; per.name = @"纽埃"; per.gender = @"男"; //把对象类型转化为二进制类型 (NSData 类型) NSMutableData * data = [NSMutableData data]; //初始化一个归档对象 创建一个归档工具 NSKeyedArchiver * archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data]; [archiver encodeObject:per forKey:@"person"];//归档操作 //结束归档 [archiver finishEncoding];//结束编码转化 [archiver release]; [per release]; //写入文件 BOOL isSuccess = [data writeToFile:[self filePath] atomically:YES]; NSLog(@"%@",isSuccess ? @"成功":@"失败"); } //反归档 - (IBAction)unArchiver:(id)sender { //拿到一个反归档的文件 Data NSData * data = [NSData dataWithContentsOfFile:[self filePath]]; //反归档的工具 NSKeyedUnarchiver * unArchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data]; //反归档 Person * per = [unArchiver decodeObjectForKey:@"person"];//根据上面的 key //结束反编码 [unArchiver finishDecoding]; [unArchiver release]; NSLog(@"姓名:%@,性别:%@",per.name,per.gender); } //指定一个文件的路径 -(NSString *)filePath{ return [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"per.data"]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
#pragma mark (.h文件)-------------------------------------------------------------------------------------------------------- #import <Foundation/Foundation.h> //供归档用的 model 类 @interface Person : NSObject <NSCoding>//服从 NSCoding 协议,支持编码的转化 @property(nonatomic,copy)NSString * name;//姓名 @property(nonatomic,copy)NSString * gender;//性别 @end #pragma mark (.m文件)-------------------------------------------------------------------------------------------------------- #import "Person.h" @implementation Person //重写 NSCoding 的协议方法 //在归档编码的时候要走的方法 - (void)encodeWithCoder:(NSCoder *)aCoder{ [aCoder encodeObject:self.name forKey:@"name"]; [aCoder encodeObject:self.gender forKey:@"gender"]; //这里的 key 可以随便给 } //在反归档的时候要走的方法 - (id)initWithCoder:(NSCoder *)aDecoder{ self = [super init]; if (self) { self.name = [aDecoder decodeObjectForKey:@"name"]; self.gender = [aDecoder decodeObjectForKey:@"gender"]; } return self; } @end
#pragma mark (.h文件)-------------------------------------------------------------------------------------------------------- #import <UIKit/UIKit.h> //关联读写文件的类 @interface WriterToFileViewController : UIViewController @end #pragma mark (.m文件)-------------------------------------------------------------------------------------------------------- // // WriterToFileViewController.m #import "WriterToFileViewController.h" @interface WriterToFileViewController () @property (retain, nonatomic) IBOutlet UITextField *tf; @end /*文件读写 支持的文件读写类型:字符串、数组、字典、NSdata (可变的、不可变的) *****对于数组、字典在写入文件时,其中的元素也必须是以上四种类型之一。 支持的数据类型有限、且简单 写入文件: 字符串写入文件: writeToFile: atomically: encoding: error 读取字符串: stringWithContentsOfFile:Encoding:error 数组的写入文件 writeToFile: atomically: 数组的读取: arrayWithContentsOfFile: 字典写入文件: writeToFile: atomically: 字典的读取: dictionaryWithContentsOfFile: */ @implementation WriterToFileViewController - (void)viewDidLoad { [super viewDidLoad]; } //字符串写入 - (IBAction)stringToWrite:(id)sender { NSString * str = self.tf.text; BOOL isSuccess = [str writeToFile:[self getFilePath] atomically:YES encoding:NSUTF8StringEncoding error:nil]; NSLog(@"%@",isSuccess?@"YES":@"NO"); } //读取字符串 - (IBAction)readToString:(id)sender { NSString * str = [NSString stringWithContentsOfFile:[self getFilePath] encoding:NSUTF8StringEncoding error:nil]; NSLog(@"读取文件——》%@",str); } //获取文件路径 -(NSString *)getFilePath{ //获取document文件夹 NSString * documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES)lastObject]; //拼接一个路径 NSLog(@"地址——》%@",documentPath); return [documentPath stringByAppendingPathComponent:@"str.txt"]; } //数组写入 - (IBAction)arraryToFile:(id)sender { //获取文件路径 NSString * arrPath = [self arrarrGetPath]; //写入数据 NSArray * arrData = @[self.tf.text,@"纽埃年为收水电费水电费的方式是电风扇的"]; BOOL isSuccess = [arrData writeToFile:arrPath atomically:YES]; NSLog(@"%@",isSuccess?@"成功":@"失败"); } //数组读取文件 - (IBAction)readArr:(id)sender { NSArray * arr = [NSArray arrayWithContentsOfFile:[self arrarrGetPath]]; NSLog(@"读取数组为:%@",arr); NSLog(@"读取数组为:%@",arr.firstObject); NSLog(@"读取数组为:%@",arr.lastObject); } //获取数组文件路径 -(NSString *)arrarrGetPath{ //获取文件夹路径 NSString * documentPath= [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject]; NSLog(@"写入数组地址——》%@",documentPath); //拼接路径 return [documentPath stringByAppendingPathComponent:@"Arrary.txt"]; } //二进制写入文件 - (IBAction)binaryToFile:(id)sender { NSData * data = [self.tf.text dataUsingEncoding:NSUTF8StringEncoding]; //获取路径 NSString * filePath = [self getFilePatherjinzhi]; [data writeToFile:filePath atomically:YES]; } //读取二进制文件 - (IBAction)readFromBinary:(id)sender { NSData * data = [NSData dataWithContentsOfFile:[self getFilePatherjinzhi]]; NSString * datastr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"读取二进制文件_>%@",datastr); } //获取文件路径 -(NSString *)getFilePatherjinzhi{ NSString * docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject]; return [docPath stringByAppendingPathComponent:@"dodpa.txt"]; } //字典写入 - (IBAction)dicToFile:(id)sender { NSString * dicStr = self.tf.text; NSDictionary * dic = @{@"NNN":@"name",dicStr:@"tf.text"}; BOOL isSuccess = [dic writeToFile:[self dicGetFilePath] atomically:YES ]; NSLog(@"%@",isSuccess?@"成功":@"失败" ); } //读取字典 - (IBAction)readFromDic:(id)sender { NSDictionary * dic = [NSDictionary dictionaryWithContentsOfFile:[self dicGetFilePath]]; NSLog(@"读取字典:%@",dic); } //获取文件路径 -(NSString *)dicGetFilePath{ NSString * documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject]; NSLog(@"字典的地址——>@%@",documentPath); return [documentPath stringByAppendingPathComponent:@"dic.txt"]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } - (void)dealloc { [_tf release]; [super dealloc]; } @end
在上面的代码里,字典的存取时候,注意键值对
self.view.frame与self.view.bounds的区别?
newView.bounds = CGRectMake(50, 50, 150, 150);//他不会改变相对于父亲视图的大小(就是自身的中心点不会改变),只会改变(自身的坐标体系)自己的坐标原点,后面的两个值是管着自身的大小,就是缩放的效果
//归档(数组)
Person * per1 = [[Person alloc]init];
per1.name = @"HHH";
per1.gender = @"男";
Person * per2 = [[Person alloc]init];
per2.name = @"TTT";
per2.gender = @"女";
[per1 autorelease];
[per2 autorelease];
NSArray * arrPer = @[per1,per2];
//
NSMutableData * ArrData = [NSMutableData data];
//创建归档工具 (就是把文件转化为二进制数据)
NSKeyedArchiver * archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:ArrData];
//归档
[archiver encodeObject:arrPer forKey:@"arrkey"];
//归档结束
[archiver finishEncoding];//这里把对象转化为对应的编码
[archiver release];
//写入文件
BOOL isSuccess = [ArrData writeToFile:[self filePath] atomically:YES];
NSLog(@"%@",isSuccess?@"数组归档成功":@"数组归档失败");
//反归档
//获取文件的路径
NSString * filePath = [self filePath];
//根据路径去接受反归档的内容,创键反规当工具
NSData * data0 = [NSData dataWithContentsOfFile:filePath];
NSKeyedUnarchiver * unArchier = [[NSKeyedUnarchiver alloc]initForReadingWithData:data0];
//反归档操作(根据上面归档的key去反归档操作)
NSArray * arr = [unArchier decodeObjectForKey:@"arrkey"];
NSLog(@"反归档得到数据_>%@ _>%@",[[arr firstObject] name],[[arr lastObject] name]);
[unArchier finishDecoding];//结束反归档
[unArchier release];
三种数据持久化
(1)用户首次登陆判断的那种数据持久化要使用:NSUSerDefault
(2)写入文件
(3)归档
归档对于复杂对象:必须服从 NScoding 协议,重写两个协议的方法。
- (void)viewDidLoad { [super viewDidLoad]; [self attributesOfFile];//获取文件夹的属性 } //获取文件夹属性 -(void)attributesOfFile{ //获取 Documents 文件夹的路径 NSString * documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]; //获取文件夹的属性 NSFileManager * manage = [NSFileManager defaultManager]; NSDictionary * dic = [manage attributesOfItemAtPath:documents error:nil]; NSLog(@"文件的大小:%@",dic[@"NSFileSize"]); //获取文件夹下的子文件夹的路径 NSArray * fileArr = [manage subpathsAtPath:documents]; //可参考 File Attribute Keys //遍历得到各个子文件夹的文件夹名字 for (NSString * path in fileArr) { NSLog(@"%@",path ); NSLog(@"详细路径_>%@",[documents stringByAppendingPathComponent:path]);//详细路径 } } //获取指定的文件夹路径 -(NSString *)getImagePath{ //首先看 Caches 文件夹路径 NSString * cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject]; //拼接到一个路径,并返回路径 return [cachesPath stringByAppendingPathComponent:@"Images"]; } - (IBAction)creatFile:(id)sender { //文件管理类,专门管理文件 NSFileManager * fileManage= [NSFileManager defaultManager]; //获取图片的文件夹路经 NSString * imagePath = [self getImagePath]; //判断文件是否存在 if (![fileManage fileExistsAtPath:[self getImagePath]]) { //如果不存在,就创建 //第一个参数:对应创建文件的路径 //第二个参数:如果路径里的某一个文件夹没有创建,给YES就是自动创建 BOOL isSuccess = [fileManage createDirectoryAtPath:imagePath withIntermediateDirectories:YES attributes:nil error:nil]; NSLog(@"%@",isSuccess?@"创建成功":@"创键失败"); } } - (IBAction)deleFile:(id)sender { NSFileManager * manage = [NSFileManager defaultManager]; //判断文件夹是否存在,存在则删除 if ([manage fileExistsAtPath:[self getImagePath]]) { BOOL isSuccess = [manage removeItemAtPath:[self getImagePath] error:nil]; NSLog(@"%@",isSuccess?@"删除缓存成功":@"删除缓存失败"); } } - (IBAction)moveFile:(id)sender { //获取移动之前的路径 NSString * perFilePath = [self getImagePath]; //取到移动之后的路径 NSString * afterFilePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"data.list"]; //移动 NSFileManager * manage =[NSFileManager defaultManager]; BOOL isSuccess = [manage moveItemAtPath:perFilePath toPath:afterFilePath error:nil]; NSLog(@"%@",isSuccess?@"移动成功":@"移动失败"); } - (IBAction)copyFile:(id)sender { //先获取文件 NSString * path = [[NSBundle mainBundle] pathForResource:@"1" ofType:@"png"]; //拷贝文件到创建的文件夹下 (沙盒中 Caches下的Images文件夹) NSString * imagePath= [self getImagePath]; //拷贝 NSFileManager * manage = [NSFileManager defaultManager]; //如果文件夹存在,就拷贝 if ([manage fileExistsAtPath:[self getImagePath]]) { BOOL isSuccess = [manage copyItemAtPath:path toPath:imagePath error:nil]; NSLog(@"%@",isSuccess?@"拷贝成功":@"拷贝失败"); } }