关闭

iOS-沙盒(二)

标签: 数据库沙盒ios数据备份
288人阅读 评论(0) 收藏 举报

一、iOS中的沙盒机制

iOS应用程序只能对自己创建的文件系统读取文件,这个独立、封闭、安全的空间,叫做沙盒。每个ios应用都有自己的应用沙盒,应用沙盒就是文件系统目录,与其他应用的文件系统隔离。它一般存放着程序包文件(可执行文件)、图片、音频、视频、plist文件、sqlite数据库以及其他文件。每个应用程序都有自己的独立的存储空间(沙盒)一般来说应用程序之间是不可以互相访问的,在ios8中已经开放访问,模拟器沙盒的位置路径:/User/userName/Library/Application Support/iPhone Simulator;当我们创建应用程序时,在每个沙盒中含有三个文件,分别是Document、Library(下面有Caches和Preferences目录)和temp。
应用程序包:包含所有的资源文件和可执行文件。


二、对Document、Library(下面有Caches和Preferences目录)和temp做简单介绍

1.Document:一般需要持久的数据都放在此目录中,可以在当中添加子文件夹,iTunes备份和恢复的时候,会包括此目录。

2.Library:设置程序的默认设置和其他状态信息,iTunes会自动备份该目录,例如杂志、新闻、地图应用使用的数据库缓存文件和可下载内容应该保存到这个文件夹。一般可以重新下载或者重新生成的数据应该保存在 <Application_Home>/Library/Caches 目录下面。
Libaray/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除。一般存放体积比较大,不是特别重要的资源。
Libaray/PreferencePanes:保存应用的所有偏好设置,ios的Settings(设置)应用会在该目录中查找应用的设置信息,iTunes会自动备份该目录。

3.temp:创建临时文件的目录,当iOS设备重启时,文件会被自动清除,只是临时使用的数据应该保存到 <Application_Home>/tmp 文件夹。iCloud 不会备份这些文件,下次启动应用自动删除。


三、获取沙盒路径

//Home目录
NSString *homeDirectory = NSHomeDirectory(); 

//Document目录
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);   
NSString *path = [paths objectAtIndex:0];   

//Cache目录
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);   
NSString *path = [paths objectAtIndex:0];   

//PreferencePanes目录
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];

//Libaray目录NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);   
NSString *path = [paths objectAtIndex:0];   

//tmp目录 
NSString *tmpDir = NSTemporaryDirectory();



四、文件夹操作(文件夹有:带扩展名.exe或者不带后缀两种)

1.创建文件夹

沙盒文件夹操作使用系统Foundation框架下的NSFileManager文件操作类实现。在沙盒中新建文件夹,需指定新建文件夹的绝对路径,然后手动创建。并且要保证新建文件夹的上级路径已经存在,否则需要先创建上级文件夹路径。文件夹的创建使用createDirectoryAtPath方法。

新建文件夹代码:

    //判断createPath路径文件夹是否已存在,此处createPath为需要新建的文件夹的绝对路径
    if ([[NSFileManager defaultManager] fileExistsAtPath:createPath]) 
    { 
        return; 
    } 
    else 
    { 
        //创建文件夹
        [[NSFileManager defaultManager] createDirectoryAtPath:createPath withIntermediateDirectories:YES attributes:nil error:nil];  
    }

其中creatPath的结构:沙盒路径\文件夹名.exe(或者沙盒路径\文件夹名),后面其他路径类&#20284;;(注意这两种方法一种生成带后缀.exe的文件夹,一中生成不带后缀名的文件夹,即使沙盒路径\文件夹名部分相同,也不是同一个文件夹

PS:如何保证新建文件夹的父亲文件夹已经存在(截取父文件夹路径验证),iOS提供了许多字符串路径的处理方法(以前是在Foundation框架的NSPathUtilities.h中,现在可用字符串直接调用)。
&#43;(NSString*)pathWithComponents:components 根据components中的元素构造有效路径
-(NSArray*)pathComponents 析构路径,获得组成此路径的各个部分
-(NSString*)lastPathComponent 提取路径的最后一个组成部分
-(NSString*)pathExtension 从路径的最后一个组成部分中提取其扩展名
-(NSString*)stringByAppendingPathComponent:path 将path添加到现有路径的末尾
-(NSString*)stringByDeletingLastPathComponent 删除路径的最后一个组成部分
-(NSString*)stringByDeletingPathExtension 从文件的最后一部分删除扩展名

其他方法可以搜索NSPathUtilities的用法自行查询

2.删除文件夹

删除文件夹,需先判定该文件夹是否存在(使用fileExistsAtPath方法),如果存在,执行删除操作(使用removeItemAtPath)

    if([[NSFileManager defaultManager] fileExistsAtPath:pathFull])//如果存在临时文件的配置文件 
    { 

        [[NSFileManager defaultManager]  removeItemAtPath:pathFull error:&error]; 
    }

3.移动文件夹

文件夹移动需要两个参数,文件夹原绝对路径与目标绝对路径。使用moveItemAtPath 方法实现

移动文件夹代码:

NSFileManager *fileManager =[NSFileManager defaultManager];

    // prePath 为原路径,cenPath 为目标路径
    if([fileManager moveItemAtPath:prePath toPath:cenPath error:&error]!=YES) 
    { 
        NSLog(@"移动文件失败"); 
    } 
    else 
    { 
        NSLog(@"移动文件成功"); 
    }

PS:文件夹移动需要注意的是,要确保目标路径中除了目标文件夹之外的路径确实存在。否则移动到一个还没有创建的文件夹下,是会失败的,这和创建文件夹是一样的。

4.重命名文件夹

重命名文件夹也需要两个参数,原绝对路径与目标绝对路径,用了一个偷换概念的方式来实现,其实用的是移动文件夹的方法。不赘述。

5.获取目录下的所有文件名称(包括文件夹与文件)

//fileNameList中即为该imagesFolder文件夹下的所有文件的名称数组
NSArray *fileNameList=[[NSFileManager defaultManager]
contentsOfDirectoryAtPath:imagesFolder error:nil];


五、文件操作

1.写入文件

写入文件需要首先判定该文件的父亲文件夹是否存在,存在则可以进行写入,否则需首先创建父亲 路径。使用writeToFile方法。写入文件的同时,系统会自动创建文件。

一般数据类型,比如数组、字典、NSData、NSString都可以直接调用writeToFile方法写入文件。

代码例子: [arrayA writeToFile:filePath atomically:YES];

也可以手动创建文件:

NSFileManager *fileManager =[NSFileManager defaultManager];
[fileManager createFileAtPath:myPath contents:[string dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];

myPath例如:@"/Users/ibokan/Desktop/login.text"

2.读取文件

如果用户知道文件内容的数据类型比较规整,则可以直接读取文件内容到标准数据结构中。

NSArray *arrayA = [[NSArray alloc]initWithContentsOfFile:filePath];

filePath例如:@"/Users/ibokan/Desktop/login.plist"

PS:或许有些时候,需要用到混合数据的写入与读取,可以使用NSMutableData实现。(其它数据类型转化为data存入,再以data形式读取后转化为原来数据类型)

3. NSFileManager一些文件方法

创建一个文件并写入数据
- (BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data attributes:(NSDictionary *)attr;
从一个文件中读取数据
- (NSData *)contentsAtPath:(NSString *)path;
移动文件
- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **) error;
复制文件
- (BOOL)copyItemAtPath:(NSString *)scrPath toPath:(NSString *)dstPath error:(NSError **) error;
比较两个文件的内容是否一样
- (BOOL)contentsEqualAtPath:(NSString *)path1 andPath:(NSString *)path2;
文件是否存在
- (BOOL)fileExistsAtPath:(NSString *)path;
移除文件
- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **) error;

4.NSFileManager一些方法代码举例

//创建文件管理
NSFileManager *fileManager = [NSFileManager defaultManager];   
NSString *path = [NSHomeDirectory( )  stringByAppendingPathComponent:@"holyBible.txt"];                                         NSString *text = @"abcdefg"; 
//将字符串转成NSData类型 
NSData *data = [text dataUsingEncoding: NSUTF8StringEncoding]; 
//写入文件 
BOOL success = [fileManager createFileAtPath:path contents:data attributes:nil];

//NSFileManager-读取内容 
NSData *fileData = [fileManager contentsAtPath:filePath];                                   
NSString *content = [[NSString alloc] initWithData:fileData dataUsingEncoding: NSUTF8StringEncoding];
//NSData-读取内容                                                                                          
NSString *filePath = [path stringByAppendingPathComponent:@"holyBible.txt"];     
NSData *data = [NSData dataWithContentOfFile:filePath];
//NSString-读取内容 
NSString *filePath = [path stringByAppendingPathComponent:@"holyBible.txt"];     
NSString *content = [[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
                                                                                            
//移动文件(重命名)
NSString *toPath = [NSHomeDirectory( ) stringByAppendingPathComponent:@"hellogod/newTestament.txt"];
[fileManager createDirectoryAtPath:[toPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil];//先建立父文件夹
NSError *error;                                                                                             
BOOL isSuccess = [fileManager moveItemAtPath:filePath toPath:toPath error:&error];

//复制文件(重命名)
NSString *copyPath = [NSHomeDirectory( ) stringByAppendingPathComponent:@"备份/Old Testament.txt"];                              [fileManager createDirectoryAtPath:[toPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil];//先建立父文件夹                                                   
BOOL success = [fileManager copyItemAtPath:toPath toPath:toPath error:nil];

//删除文件、获取文件大小
//判断文件是否存在和删除文件                                                                              
if([fileManager fileExistsAtPath:copyPath])
{                      
 if ([fileManager removeItemAtPath:copyPath])  
 {                                                                                
  NSLog(@"remove success");
 }                                                                                                                  
}

//获取文件大小  
NSFileManager *fileManager = [NSFileManager defaultManager];                        
//获得文件的属性字典
NSDictionary *attrDic = [fileManager attributesOfItemAtpath:sourcePath error:nil];  
NSNumber *fileSize = [attrDic objectForKey:NSFileSize];  
 
//获取目录文件信息
NSFileManager *fileManager = [NSFileManager defaultManager];                         
NSString *enuPath = [NSHomeDirectoty( ) stringByAppendingPathComponent:@"Test"];                                                NSDictionaryEnumerator *dirEnum = [fileManager enumeratorAtPath:enuPath];     
NSString *path = nil;                                                                                      
while ((path = [dirEnum nextObject]) != nil){                            
NSLog(@"%@",path);                                                                                       
}

六、几个可能会用到的例子

1.获取应用程序程序包中资源文件路径的方法以及复制资源包中文件到沙盒:

//例如获取程序包中一个图片资源(apple.png)路径的方法:
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@”apple” ofType:@”png”];
UIImage *appleImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
//代码中的mainBundle类方法用于返回一个代表应用程序包的对象。

有时候我们建数据库文件,不喜欢用代码直接建,可能会用火狐的工具,建完之后拖入工程,但是这是数据库不可进行增删改操作,只有放入沙盒,所以要把它复制到沙盒里面,代码如下:

//沙盒目标路径
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
    NSString *sqlFilePath = [docPath stringByAppendingPathComponent:@"ShuJuKu.sqlite"];

    //原始项目路径
    NSString *orignFilePath = [[NSBundle mainBundle] pathForResource:@"ShuJuKu" ofType:@"sqlite"];
    NSFileManager *fm = [NSFileManager defaultManager];
    //如果doc下没有数据库,从bundle里面拷贝过来
    if([fm fileExistsAtPath:sqlFilePath] == NO)
    {
        NSError *err = nil;
        //如果拷贝失败
        if([fm copyItemAtPath:orignFilePath toPath:sqlFilePath error:&err] == NO)
        {
            NSLog(@"拷贝失败,原因: %@",[err localizedDescription]);
            return nil;
        }
    }

2.举一个图片存入沙盒以及从沙盒读取的例子
//图片存储到沙盒中
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@“gg.png"]];// 保存文件的名称
[UIImagePNGRepresentation(myImage)writeToFile: filePath atomically:YES];
//myImage就是那张要保存的图片

//读取
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"myImage.png", (int)current]];// 保存文件的名称
UIImage *img = [UIImage imageWithContentsOfFile:filePath];

PS:有时候我们需要批量存储图片的时候,可以把图片转化为NSData类型存入plist文件,然后把plist文件存入沙盒(可能会导致文件过大);也可以把图片存入沙盒,然后把图片存放路径存入plist,之后再把plist文件存入沙盒。
0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2628次
    • 积分:109
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:4篇
    • 译文:0篇
    • 评论:0条
    文章分类