iOS-沙盒(二)

一、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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS和安卓的沙盒是用来保护应用程序数据的安全性的一种机制。它们的主要区别如下: 1. 安全性:iOS沙盒机制相对安卓更加严格。iOS要求应用程序在自己的沙盒内运行,限制了应用之间的直接访问和交互。而安卓的沙盒机制相对较弱,应用程序可以更容易地访问和共享数据。 2. 文件系统结构:iOS沙盒机制将每个应用程序的文件分隔为多个目录,包括应用程序包、文档目录、缓存目录等。每个目录只能由特定的应用程序进行访问和写入。而安卓的沙盒机制通常是基于应用的用户ID,并且应用程序可以自由地向沙盒中的文件系统写入和访问。 3. 权限管理:iOS沙盒机制通过权限管理来限制应用程序对系统资源的访问。应用程序需要在安装时声明所需的访问权限,并由用户在使用时授予。而安卓的沙盒机制在应用程序安装时会一次性获取所有权限,并且用户只能在软件设置中进行修改。 4. 应用程序的更新:iOS沙盒机制要求每个应用程序都在单独的容器中运行,因此应用程序的更新通常是通过替换整个应用程序包来完成的。而安卓的沙盒机制允许应用程序在更新时只替换其中的部分文件,从而减少下载和更新时间。 综上所述,iOS和安卓的沙盒机制在安全性、文件系统结构、权限管理和应用程序更新方面存在一些差异。iOS沙盒机制相对更严格,保护了应用程序和用户数据的安全性,但也可能限制了应用程序之间的交互。而安卓的沙盒机制相对较弱,允许应用程序更自由地访问和共享数据,但也可能增加了安全隐患。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值