ios 文件存储

来源:互联网 发布:软件售后服务方案 编辑:程序博客网 时间:2024/06/03 16:37

一,沙盒

iOS 中的沙盒机制(SandBox)是一种安全体系。
每个 iOS 应用程序都有一个单独的文件系统(存储空间),而且只能在对应的文件系统中进行操作,此区域被称为沙盒。所有的非代码文件都要保存在此,例如属性文件 plist、文本文件、图像、图标、媒体资源等。
Application:存放程序源文件,上架前经过数字签名,上架后不可修改,由于应用程序必须经过签名,所以不能在运行时对这个目录中的内容进行修改,否则会导致应用程序无法启动。
每个应用沙盒含有3个文件夹:Documents, Library 和 tmp
如图
1,Documents:常用目录,iCloud备份目录,存放数据,这里不能存缓存文件,否则上架不被通过,保存应用程序的重要数据文件和用户数据文件等。iTunes 同步时会备份该目录
2,Library:
&Caches:保存应用程序使用时产生的支持文件和缓存文件,还有日志文件最好也放在这个目录。iTunes 同步时不会备份该目录。比如下载的音乐,视频,SDWebImage缓存等
&Preference:设置目录,iCloud会备份设置信息
3,tmp:存放临时文件,不会被备份,而且这个文件下的数据有可能随时被清除的可能,按照官方说法每三天清理一次缓存数据.
对于上述描述可以这样举例理解,一个记事本应用,用户写的东西需要保存起来,这些东西是用户自行生成的,则需要放在 Documents 目录里。一个新闻应用,如果需要从服务器下载东西展示给用户看,下载的东西就放在 Library/Caches 目录里。苹果审核对这个要求很严格,主要原因是 iCloud 的同步问题。
(1).获取沙盒文件对应的存储路径

//沙盒的根路径    NSString *rootPath = NSHomeDirectory();    //获取Documents目录    //[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);    NSString *documentsDirectory = [paths objectAtIndex:0];    //获取Library路径    //[NSHomeDirectory() stringByAppendingPathComponent:@"Library"];    NSArray *libPaths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);    NSString *libraryDirectory = [libPaths objectAtIndex:0];    //获取Library路径下的catch 路径    NSArray *cacPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);    NSString *cachePath = [cacPath objectAtIndex:0];    //[NSHomeDirectory() stringByAppendingPathComponent:@"tmp"];    NSString *tmp = NSTemporaryDirectory();    //拼接路径     NSString *tempFilePath = [tmp stringByAppendingPathComponent:@".File"];   }

(2).使用NSFileManager操作文件

NSString *mypath  = @"你要操作的文件路径";    //拼接路径    NSString *doctorPath = [mypath stringByAppendingPathComponent:@"test"];    //创建文件管理器对象    NSFileManager *manager = [NSFileManager defaultManager];    //创建文件夹    NSError *error = nil;   BOOL iscreateSuccess = [manager createDirectoryAtPath:doctorPath withIntermediateDirectories:YES attributes:nil error:&error];    //创建文件    NSString *filePath = [doctorPath stringByAppendingPathComponent:@"test.txt"];    NSData *filecontent = [@"hello world" dataUsingEncoding:NSUTF8StringEncoding];    BOOL iscreateFileOk = [manager createFileAtPath:filePath contents:filecontent attributes:nil];    //写入数据到文件   BOOL isWriteOk = [@"mydata for me" writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];    //读取数据   //1 NSData *data = [NSData dataWithContentsOfFile:filePath];  NString datacontent =  [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];    //删除文件  BOOL isDeleteOk = [manager removeItemAtPath:filePath error:nil];

二,使用 plist存储

特点:(1)只能存储OC常用数据类型(NSString、NSDictionary、NSArray、NSData、NSNumber等类型)而不能直接存储自定义模型对象
(2).如果想存储自定义模型对象 -> 只能将自定义模型对象转换为字典存储;
(3).使用前提条件:一个对象必须实现了writeToFile方法,因为我们是通过调用对象的writeToFile方法将对象写入到一个plist文件中的
(4). plist只能识别字典,数组

获取文件路径,同上沙盒路径

//文件存储的位置(同上) +(NSString*)getFilePath{    NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;    //拼接要保存的路径    NSString *filePath = [path stringByAppendingPathComponent:FILEPATH];    return filePath ;}

写入要存储的数据

+(void)writeToFile:(id)data{    if ([data isKindOfClass:[NSDictionary class]]) {        NSDictionary *dicdata = (NSDictionary *)data ;        [dicdata writeToFile:[MyPlist getFilePath] atomically:YES];    }else if([data isKindOfClass:[NSArray class]]){        NSArray *arrdata = (NSArray*)data ;        [arrdata writeToFile:[MyPlist getFilePath] atomically:YES];    }else{        NSLog(@"error");    }}

读取plist文件数据

+(id)readFromFile{    Boolean isdictionary = YES ;    if(isdictionary){        NSDictionary *dic = [NSDictionary dictionaryWithContentsOfFile:[MyPlist getFilePath]];        return dic ;    }else{        NSArray *array = [NSArray arrayWithContentsOfFile:[MyPlist getFilePath]];        return array ;    }}

三,归档 NSKeyedArchiver

这个有点像java序列化serializable
特点:
(1).可以存储自定义模型对象
NSKeyedArchiver归档相对较plist存储而言,它可以直接存储自定义模型对象,而plist文件需要将模型转为字典才可以存储自定义对象模型;
(2).归档不能存储大批量数据(相比较Sqlite而言),存储数据到文件是将所有的数据一下子存储到文件中,从文件中读取数据也是一下子读取所有的数据;
缺点:
(3).假如你的文件中有多个对象,然后你想在利用归档添加一个对象,你需要先把所有的数据解档出来,然后再加入你想添加的那个对象,同理,你想删除一个文件中的一个对象也是,需要解档出所有的对象,然后将其删除。这样处理性能低下
(4).关于使用:需要归档的模型类必须要遵守NSCoding协议,然后模型实现类中必须实现两个方法:1>encodeWithCoder -> 归档;2> initWithCoder: - > 解档

(5). 使用注意:

如果父类也遵守了NSCoding协议,请注意:

应该在encodeWithCoder:方法中加上一句

[super encodeWithCode:encode]; // 确保继承的实例变量也能被编码,即也能被归档

应该在initWithCoder:方法中加上一句

self = [super initWithCoder:decoder]; // 确保继承的实例变量也能被解码,即也能被恢复
// 1. 自定义模型类Person// 1.1 Person.h文件#import <Foundation/Foundation.h>// 只要一个自定义对象想要归档,必须要遵守NSCoding协议,并且要实现协议的方法@interface Person : NSObject<NSCoding>@property (nonatomic, assign) int age;@property (nonatomic, strong) NSString *name;@end// 1.2 .m实现文件#import "Person.h"#define KName @"name"#define KAge @"age"@implementation Person// 什么时候调用:当一个对象要归档的时候就会调用这个方法归档// 作用:告诉苹果当前对象中哪些属性需要归档- (void)encodeWithCoder:(NSCoder *)aCoder{    [aCoder encodeObject:_name forKey:KName];    [aCoder encodeInt:_age forKey:KAge];}// 什么时候调用:当一个对象要解档的时候就会调用这个方法解档// 作用:告诉苹果当前对象中哪些属性需要解档// initWithCoder什么时候调用:只要解析一个文件的时候就会调用- (id)initWithCoder:(NSCoder *)aDecoder{    #warning  [super initWithCoder]    if (self = [super init]) {        // 解档        // 注意一定要记得给成员属性赋值      _name = [aDecoder decodeObjectForKey:KName];      _age = [aDecoder decodeIntForKey:KAge];    }    return self;}@end// 2. 实例 -基本使用:取 / 存 数据 // 归档 [NSKeyedArchiver archiveRootObject: self.persons toFile:KFilePath];// 将self.persons模型对象数组  // 解档        _persons = [NSKeyedUnarchiver unarchiveObjectWithFile:KFilePath];

四,sqlite 数据库使用

sqlite原生数据库,需要写sql语句
sqlite数据库使用

使用Coredata映射型数据库,这个底层还是sqlite数据库实现的
coreData初步认识

原创粉丝点击