iOS 沙盒&NSFileManager&归档

创建文件夹、创建文件、文件夹里面创建文件

一.几种沙盒常用的存储方式

1. 项目中常用的NSUserDefaults存放的地址是:Library/Preferences,里面以bundleId为名的偏好设置plist文件里面;
   Library/Preferences包含应用程序的偏好设置文件,您不应该直接创建偏好设置文件,而是应该使用NSUserDefaults类来取得和设置应用程序的偏好。
2. 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦;
3. 归档:因为间接(NSUserDefaults)或者直接操作使用plist文件,只能存储常用的类型, 而归档可以实现把自定义的对象存放在文件中。

二. 存取的方式
通常用fileManager写入的例如页面信息等大量缓存等存放地址是:Library/Caches; 写入的运行过程产生的如用户信息等需要持久化的数据,可以写入document。
NSUserDefaults直接写入后,是默认存放在系统偏好设置的plist文件(registerDefaults方法除外,它没有写入plist)。

fileManager写入:

1. 先创建路径(也就文件夹路径):
        NSFileManager *fileM = [NSFileManager defaultManager];
        NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"wgj01"];
        if (![fileM fileExistsAtPath:documentsPath]) { 
            [fileM createDirectoryAtPath:documentsPath withIntermediateDirectories:YES attributes:nil error:nil];
        }

2. 写入方式一:
        NSString *filePath = [documentsPath stringByAppendingPathComponent:@"w"];
        NSDictionary *dict = @{@"w":@"wwww"};
        [dict writeToFile:filePath atomically:YES];
这样写入之后,在NSCachesDirectory里面的wgj01文件夹中有一个w文件,因为没有后缀,所以存放格式为xml格式。

3. 写入方式二:
        NSString *filePath = [documentsPath stringByAppendingPathComponent:@"ws.plist"];
        NSDictionary *dict = @{@"w":@"wwww"};
        [dict writeToFile:filePath atomically:YES];
文件ws有后缀,写入的是plist格式。

3.1 针对3 的读取&修改方式:
     //读取:
      NSString *filePath = [documentsPath   stringByAppendingPathComponent:@"ws.plist"];
      NSMutableDictionary *dataDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
         NSLog(@"\n\n\n%@",dataDict);
     //修改或添加:
        [dataDict setObject:@"mmmmm" forKey:@"m"];
        [dataDict writeToFile:filePath atomically:YES];

3.2   对于项目文件中的plist文件:
      NSString *filePath = [[NSBundle mainBundle] pathForResource:@"wgjTT" ofType:@"plist"];
     和沙盒里面的plist文件(上面3.1)一样,对解析出来的字典或者数组进行增删改等操作,
但是,操作后,点击查看plist文件,发现没有变化,而,打印:
        NSMutableDictionary *dataDictafter = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath1];
        NSLog(@"\n\n\nTT0:\ndataDictafter:\n%@",dataDictafter);
发现,打印结果时改变后的结果。

猜测:应该是只写入了缓存,等程序重新运行,打印plist数据结果还是修改前的结果(plist并未有实质性的改变)。

4. 写入方式三:
        NSString *filePath = [documentsPath stringByAppendingPathComponent:@"wh"];
        NSDictionary *dict = @{@"w":@"wwww"};
        NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
        [fileM createFileAtPath:filePath contents:data attributes:nil];
这样,在wgj01文件夹下有一个wh文件,它里面的格式为:json格式。
eg.
{
  "w" : "wwww"
}

4.1 针对4的读出方式:
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"wh"];
 NSData *data =  [NSData dataWithContentsOfFile:filePath];
 NSDictionary *object11 = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableContainers) error:nil];
        NSLog(@"\n\n\n%@",object11); //读取成功

5. 若想要继续创建文件夹,用stringByAppendingPathComponent后面拼接文件夹名称 并且 用        if (![fileM fileExistsAtPath:documentsPath]) {
            [fileM createDirectoryAtPath:documentsPath withIntermediateDirectories:YES attributes:nil error:nil];
        }创建文件夹。

沙盒路径各目录用途:

Documents 目录:您应该将所有de应用程序数据文件写入到这个目录下。这个目录用于存储用户数据或其它应该定期备份的信息。

AppName.app 目录:这是应用程序的程序包目录,包含应用程序的本身。由于应用程序必须经过签名,所以您在运行时不能对这个目录中的内容进行修改,否则可能会使应用程序无法启动。

Library 目录:这个目录下有两个子目录:Caches 和 Preferences

Library/Preferences 目录:包含应用程序的偏好设置文件。您不应该直接创建偏好设置文件,而是应该使用NSUserDefaults类来取得和设置应用程序的偏好.

Library/Caches 目录:用于存放应用程序专用的支持文件,保存应用程序再次启动过程中需要的信息。

tmp 目录:这个目录用于存放临时文件,保存应用程序再次启动过程中不需要的信息。

1  应用程序包:包含所有资源文件和可执行文件  
2  Documents:保存应用运行时生成的需要持久化的数据,iTunes会自动备份该目录  
3  tmp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除,应用没有运行时,系统也可能会自动清理该目录下的文件,iTunes不会同步该目录,iPhone重启时该目录下的文件会丢失。
4  Libaray:存储程序的默认设置和其他状态信息,iTunes会自动备份该目录。  
5  Libaray/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除,一般存放体积比较大,不是很重要的资源  
6  Libaray/Preferences:保存应用的所有偏好设置,ios的Settings(设置)应用会在该目录中查找应用的设置信息,iTunes会自动备份该目录。

沙盒路径地址的获取:

1,获取家目录路径的函数:  
NSString *homeDir = NSHomeDirectory();  
2,获取Documents目录路径的方法:  
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
NSString *docDir = [paths objectAtIndex:0];  
3,获取Caches目录路径的方法:  
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);  
NSString *cachesDir = [paths objectAtIndex:0];  
4,获取tmp目录路径的方法:  
NSString *tmpDir = NSTemporaryDirectory();  
5,获取应用程序程序包中资源文件路径的方法:  
例如获取程序包中一个图片资源(apple.png)路径的方法:  
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@”apple” ofType:@”png”];  
UIImage *appleImage = [[UIImage alloc] initWithContentsOfFile:imagePath];  
代码中的mainBundle类方法用于返回一个代表应用程序包的对象。

e.g.

NSString *Path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSLog(@"目录:%@",Path);
    
    NSString *dataStr1 = @"testdata";
    NSString *dataStr2 = @"wgjwgj";
    NSString *dataStr3 = @"umeng";
    
    NSData *data1 = [dataStr1 dataUsingEncoding:NSUTF8StringEncoding];
    NSData *data2 = [dataStr2 dataUsingEncoding:NSUTF8StringEncoding];
    NSData *data3 = [dataStr3 dataUsingEncoding:NSUTF8StringEncoding];
    
    NSString *path1 = [Path stringByAppendingPathComponent:@"wgjTest1"];
    NSString *path2 = [Path stringByAppendingPathComponent:@"wgjTest2"];
    
    NSString *path4 = [Path stringByAppendingPathComponent:@"wgjjm"];
    
    NSFileManager *fileManager1 = [NSFileManager defaultManager];
    //创建文件夹
    [fileManager1 createDirectoryAtPath:path4 withIntermediateDirectories:YES attributes:nil error:nil];
    //创建文件
    [fileManager1 createFileAtPath:path1 contents:data1 attributes:nil];
    [fileManager1 createFileAtPath:path2 contents:data2 attributes:nil];
    //文件夹里面创建文件
    NSString *path5 = [path4 stringByAppendingPathComponent:@"wgj5"];
    [fileManager1 createFileAtPath:path5 contents:data3 attributes:nil];
    
    NSURL *url = [NSURL fileURLWithPath:Path isDirectory:YES];
    //遍历url这个相应的目录下的文件和文件夹以及文件夹中的文件,得出文件夹/文件目录,和文件大小
    NSDirectoryEnumerator *fileEnumerator = [fileManager1 enumeratorAtURL:url
                                               includingPropertiesForKeys:@[NSFileSize]
                                                                  options:NSDirectoryEnumerationSkipsHiddenFiles
                                                             errorHandler:NULL];
    NSUInteger fileCount = 0;
    NSUInteger totalSize = 0;
    for (NSURL *fileURL in fileEnumerator) {
        NSNumber *fileSize;
        [fileURL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:NULL];
        totalSize += fileSize.unsignedIntegerValue;
        fileCount += 1;
    }

YYModel的yy_modelEncodeWithCoder和yy_modelInitWithCoder
1. 当自己实现归档archive的时候,需要实现<NSCoding>协议encode和code方法,并且需要把类里面的所有属性在encode和code方法中全部罗列操作一遍,很是麻烦,所以就可以使用YYModel的归档;
2. YYModel实现归档主要点:
    a. 把属性分为几种类型,它把int bool等数值类型都转为了NSNumber类型并使用encodeObject:forKey: 直接当成object处理。
    b. 把类对象的结构直接映射拿了出来,并映射到YY自己自定义的结构,之后循环判断此类和父类一直向上找,取出所有的属性并操作赋值。此取出属性,包括了类所有父类的自定义属性。
    c. 通过objc_property_attribute_t获取成员变量的类型,并通过字符判断具体类型返回类型枚举以供使用。

MJModel的mj_decode和mj_encode
1. 其实mj的encode原理和YY的差不多,只不过,mj只是利用的objc_property_t的runtime方法,没有自定义和系统类相似的结构做映射;也是循环类的诸多父类,找出所有的自定义属性。
2. 因为没有做结构体的映射,所以表面看起来稍微简单些。
3. 在encode的时候,也是把数值布尔等类型转化为NSNumber类型,进行encodeObject;具体做法是根据方法property_getAttributes,获取类型字符串然后截取,如果是q或者i等等数值类型,就归为NSNumber。

NSKeyedArchiver
  1. 对单个对象归档解挡
方式a.    归: NSData *arData = [NSKeyedArchiver archivedDataWithRootObject:model1];
    [arData writeToFile:path1 atomically:YES];
    解:    NSData *resultData = [NSData dataWithContentsOfFile:path1];
    id result = [NSKeyedUnarchiver unarchiveObjectWithData:resultData];
方式b. 归:BOOL isSuccess = [NSKeyedArchiver archiveRootObject:model1 toFile:path1];
    解:id result = [NSKeyedUnarchiver unarchiveObjectWithFile:path1];

  1. 对多个对象归档解挡
1.  归:   NSMutableData *data = [NSMutableData data];
    NSKeyedArchiver *archive1 = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archive1 encodeObject:@"13223432342" forKey:@"111"];
    [archive1 encodeObject:model forKey:@"222"];
    [archive1 finishEncoding];
    BOOL is1 = [data writeToFile:path1 atomically:YES];
解:    NSData *data2 = [NSData dataWithContentsOfFile:path1];
    NSKeyedUnarchiver *archive2 = [[NSKeyedUnarchiver alloc] initForReadingWithData:data2];
    id result21 = [archive2 decodeObjectForKey:@"111"];
    id result22 = [archive2 decodeObjectForKey:@"222"];
    NSLog(@"resut21:%@\n result22:%@",result21,result22);

注意:多个对象initForWritingWithMutableData归档时,finishEncoding方法之后,不能在归档,再写encode会报错;所以这个和数据库不一样,也就不能在多个地方写入,只能一次性写入,如多次针对同路径文件写入,需要创建多次keyArchive,原来的文件内容会被清掉,只保存最近的写入内容。
单个对象归档也是一样,是直接清掉之前并写入新的信息。

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

推荐阅读更多精彩内容