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;
}
View Code AppDelegate文件
#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
View Code ArchiverController文件
#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
View Code Person文件
#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
View Code WriterToFileViewController文件

在上面的代码里,字典的存取时候,注意键值对

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?@"拷贝成功":@"拷贝失败");
    }
}
View Code 文件夹的相关操作
原文地址:https://www.cnblogs.com/benpaobadaniu/p/4845487.html