数据处理之文件读写

数据持久化的方式
1.属性列表property.plist
2.NSUserDefaults(偏好设置)
3.write to file(写入文件)
4.sqlite(iOS中的轻量级数据库)
5.CoreData(苹果基于sqlite封装的数据管理方式)

可视化的源码都是xml
documents:用来保存应用程序运行需要的持久化数据,通常是用户固定需要的数据,iTunes在自动备份时会自动备份此文件夹。

// 参数
// 1.主路径名称
// 2.当前用户(iOS端默认使用NSUserDomainMask)
// 3.是否使用绝对路径
// YES绝对路径-NO相对路径~(Domain领域,区域)
NSString *documentPath = [NSSearchPathForDirectoriesInDomains( 
                                           NSDocumentDirectory, 
                                           NSUserDomainMask, 
                                           YES) objectAtIndex:0];

library:通常用来存储当前应用程序运行期间需要的一些内存,包括缓存和偏好设置。

 NSString *libraryPath = NSSearchPathForDirectoriesInDomains(
                                           NSLibraryDirectory, 
                                           NSUserDomainMask, 
                                           YES)[0];   

caches:用来存放缓存文件,但是iTunes并不会备份此文件夹。

NSString *cachePath = [NSSearchPathForDirectoriesInDomains(
                                           NSCachesDirectory, 
                                           NSUserDomainMask,
                                           YES)firstObject];

preferences:用来存储应用的偏好设置,iTunes会自动备份此文件夹。

但是此文件夹不能被直接被寻找到,需要路径拼接,因为我们一般不会直接操作保存用户的偏好设置的内容,而是通过操作来使对应的代码生效,然后存储到这个文件夹。比如NSUserDefaults

NSString *preferencesPath = [NSSearchPathForDirectoriesInDomains(
                                           NSPreferencePanesDirectory, 
                                           NSUserDomainMask, 
                                           YES)firstObject];
NSLog(@"%@",preferencesPath);// 能打印出来但是没有此地址的数据

NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[ud setObject:@"游客" forKey:@"use_id"];
[ud setBool:YES forKey:@"NightModel"];
[ud setInteger:11 forKey:@"time"];

tmp:用来存放临时文件的文件夹。程序运行期间有可能里面的文件会时不时消失掉,所以永远不要使用此文件夹来存储需要持久化得数据。iTunes不会备份此文件夹。

NSString *tmpPath = NSTemporaryDirectory();

包文件

// 路径
NSString *bundlePath = [[NSBundle mainBundle]resourcePath];
NSLog( @"%@",bundlePath);
// 获取包内文件
NSString *imagePath = [[NSBundle mainBundle]pathForResource:@"12" ofType:@"jpg"];
UIImage *image =  [UIImage imageWithContentsOfFile:imagePath];

简单对象写入文件

1.字符串写入文件
NSString *incantation = @"I love my iOS teacher!";

NSString *path = [NSSearchPathForDirectoriesInDomains(
                                  NSDocumentDirectory,
                                  NSUserDomainMask, 
                                  YES)lastObject];
//path = [path stringByAppendingString:@"/a.txt"];//拼接地址文件

//path = [path stringByAppendingPathComponent:@"b.txt"];

path = [path stringByAppendingPathComponent:@"许晟馗@郝文举.avi"];
//写入文件
// 参数
// 1.路径,传入一个文件写入的地方,并且提供文件名称
// 2.YES为安全保护,在文件写入时如果中断了操作,那么操作恢复时可以保证文件的完整性。NO,不作任何保护。
// 3.数据写入文件的编码方式。
// 4.错误对象。
NSError *error = nil;
[incantation writeToFile:path 
              atomically:YES 
                encoding:NSUTF8StringEncoding 
                   error:&error];  
// 从文件中读取
NSString *result = [NSString stringWithContentsOfFile:path 
                                             encoding:NSUTF8StringEncoding
                                                error:nil];
NSLog(@"%@",result);
全局属性NSString *docPath;
self.docPath = [NSSearchPathForDirectoriesInDomains(
                                 NSDocumentDirectory, 
                                 NSUserDomainMask,
                                 YES)lastObject];  
2.数组写入文件
// 准备数组
NSArray *array = @[@1,@2,@3,@4];
// 准备即将写入的路径
NSString *path0 = [self.docPath stringByAppendingPathComponent:@"array"];
// 将数组写入路径
[array writeToFile:path0 atomically:YES];
// 根据路径读取数组
NSArray *resultArray = [NSArray arrayWithContentsOfFile:path0];
// 打印验证结果
NSLog(@"%@",resultArray);
3.字典写入
NSDictionary *dict = @{@"1":@"q",@"2":@"w",@"3":@"e"};

NSString *path1 = [self.docPath stringByAppendingPathComponent:@"dict"];

[dict writeToFile:path1 atomically:YES];

NSDictionary *resultDict = [NSDictionary dictionaryWithContentsOfFile:path1];

NSLog(@"%@",resultDict);
4.复杂对象写入文件
// 二进制流文件写入文件

UIImage *image0 = [UIImage imageNamed:@"12.jpg"];
// 使用JPEG的渲染方式将图片转化为二进制流
// 第一个参数为需要转化的图片,第二个为压缩比例,范围为0~1
// UIImagePNGRepresentation(UIImage * _Nonnull image)

NSData *data = UIImageJPEGRepresentation(image0, 1);

NSString *path2 = [self.docPath stringByAppendingPathComponent:@"aaa.jpg"];

[data writeToFile:path2 atomically:YES];
// 从文件中获取图片
UIImage *resultImage = [UIImage imageWithContentsOfFile:path2];
真正的深拷贝只有归档和反归档
SingleVip * s1 = [SingleVip new];
s1.name = @"张河山";
s1.age = 20;
s1.gender = @"male";

// 归档(将复杂对象转化为NSData的方式)

// 创建可变的二进制流用来存放即将转化的model数据
NSMutableData *mutdata = [NSMutableData new];
// 创建归档管理器,并制定要使用的可变二进制流控制器
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:mutdata];
// 归档操作(key值用于标记,方便饭归档时提取内容)
[archiver encodeObject:s1 forKey:@"s11"];
// 结束归当操作
[archiver finishEncoding];
// 写入文件
NSString *path6 = [self.docPath stringByAppendingPathComponent:@"s1"];
[mutdata writeToFile:path atomically:YES];

// 反归档

// 从文件中获取NSData数据
NSData *data0 = [NSData dataWithContentsOfFile:path6];
// 创建反归档管理器,并制定要获取的data数据来源
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc ]initForReadingWithData:data0];
// 反归档操作(根据归档时标记的key只操作)
SingleVip *s2 = [unarchiver decodeObjectForKey:@"s11"];
// 结束反归档
[unarchiver finishDecoding];
NSLog(@"%@-+-%@",s1,s2);
浅拷贝地址一样,就是两个指针指向同一地区,深拷贝地址不一样,是因为重新开辟地区放入相同事物
SingleVip * s1 = [SingleVip new];
SingleVip * s2 = [SingleVip new];

/*
  没有真正意义上的深拷贝,除了归档和反归档,
  因为可变数组的深拷贝虽然数组指针地址不同
  但是里面同一个元素(model)的地址还是一样。
*/
// 浅拷贝(不可变变不可变)
NSArray *array = @[s1,s2];
NSArray *_array = [array copy];
NSLog(@"%p-%p",array,_array);

// 深拷贝(不可变变可变)
NSArray *array1 = @[s1,s2];
NSMutableArray *mutArray = [array mutableCopy];
NSLog(@"%p-%p",array1,mutArray);
// 深拷贝(可变变不可变)
NSMutableArray *mutArray2 = [NSMutableArray arrayWithObjects:s1,s2, nil];
NSArray *array2 = [mutArray copy];// copy出的都是不可变的
NSLog(@"%p-%p",array2,mutArray2);
// 深拷贝(可变变可变)
NSMutableArray *mutArray3 = [mutArray2 mutableCopy];
NSLog(@"%p-%p",mutArray2,mutArray3);
    
SingleVip *s3 = [s1 copy];
NSLog(@"%p-%p",s1,s3);
SingleVip *s4 = [s1 mutableCopy];
NSLog(@"%p-%p",s1,s4);
点击方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    // 因为是单例,所以在程序的任何地方都可以获取
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
   // 可以获取存储在属性列表里面的值,然后作相应的操作
    if ([[ud objectForKey:@"use_id"] isEqualToString:@"游客"]) {
   
       NSLog(@"尊敬的用户请您登陆!");
    }
}

自定义的model类创建的复杂对象,无法响应writeToFile消息,不能直接写入文件。所以想要完成转化,需遵循NSCoding协议,实现两个编码方法。
在归档过程中,需要自定义实现归档的细节,将简单对象使用key值标记完成归档记录
在反归档过程中,同样需要根据归档记录时的标记来解码,完成属性值的对应

.h

#import <Foundation/Foundation.h>

@interface SingleVip : NSObject<NSCoding,NSCopying,NSMutableCopying>

@property(strong,nonatomic,nonnull)NSString  *name;
@property(assign,nonatomic)NSInteger  age;
@property(strong,nonatomic,nullable)NSString  *gender;

@end        

.m

#import "SingleVip.h"

@implementation SingleVip

// 归档(编码)
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    // 逐条
    [aCoder encodeObject:_name forKey:@"name"];
    [aCoder encodeInteger:_age forKey:@"age"];
    [aCoder encodeObject:_gender forKey:@"gender"];
}
// 反归档(解码)
- (instancetype)initWithCoder:(NSCoder *)aDecoder{

    if (self = [super init]) {
        _name = [aDecoder decodeObjectForKey:@"name"];
        _age = [aDecoder decodeIntegerForKey:@"age"];
        _gender = [aDecoder decodeObjectForKey:@"gender"];
    }

    return self;
}
// 要实现深浅拷贝,首先要遵循NSCopying协议,然后写一下方法->copyWithZone
/*
- (id)copyWithZone:(NSZone *)zone{
// 浅拷贝直接返回self
    return self;
}

- (id)mutableCopyWithZone:(NSZone *)zone{

    return self;
}
*/
- (id)copyWithZone:(NSZone *)zone{
    // 深拷贝
    id obj = [[[self class] allocWithZone:zone] init];

    return obj;
}

- (id)mutableCopyWithZone:(NSZone *)zone{

    // 深拷贝
    id obj = [[[self class] allocWithZone:zone] init];

    return obj;

}

@end  
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容