沙盒就是应用程序的安装过程中、系统为每个单独的应用程序生成它的主目录和一些关键的子目录 — 文件夹。
沙盒机制是一种安全体系,它规定了应用程序只能在本应用程序沙盒中读取文件,不可以访问其他地方的内容。所有的非代码文件都保存在这个地方,比如图片、音频、视频、属性列表(偏好设置)和文本文件等。
优点 安全 每个应用程序都在自己的沙盒内 不能随意跨越自己的沙盒区访问别的应用程序沙盒的内容,应用程序向外请求或接受数据都需要经过权限认证
缺点 文件访问受限 访问文件不灵活
每个iOS应用都被限制在“沙盒”中,“沙盒”相当于一个加了仅主人可见权限的文件夹,苹果对沙盒有以下几条限制。
(1)、应用程序可以在自己的沙盒里运作,但是不能访问任何其他应用程序的沙盒。
(2)、应用程序间不能共享数据,沙盒里的文件不能被复制到其他应用程序文件夹中,也不能把其他应用程序文件夹中的文件复制到沙盒里。
(3)、苹果禁止任何读、写沙盒以外的文件,禁止应用程序将内容写到沙盒以外的文件夹中。
如何找到Sandbox路径?
点击屏幕—菜单栏显示Finder——前往(按住option键)—资源库—Application support——iPhone simulator——7.1——Applications 下存放的是应用程序对应的沙盒;
绝对路径:
/Users/Camille/Library/Application Support/iPhone Simulator/7.1/Applications/3B41BD98-C84D-4C82-84C1-D602CFF55475/Documents
相对路径: ~当前域
~/Library/Application Support/iPhone Simulator/7.1/Applications/3B41BD98-C84D-4C82-84C1-D602CFF55475/Documents
应用程序在运行时,会随机生成一个32位 数字加字母的字符串
目录结构
1.xxxx.app
该目录包含了应用程序本身的数据,包括资源文件和可执行文件等。程序启动以后,会根据需要从该目录中动态加载代码或资源到内存,这里用到了lazy loading的思想。
②整个目录是只读的
为了防止被篡改,应用在安装的时候会将该目录签名。非越狱情况下,该目录中内容是无法更改的;在越狱设备上如果更改了目录内容,对应的签名就会被改变,这种情况下苹果官网描述的后果是应用程序将无法启动
2、Documents
我们可以将应用程序的数据文件保存在该目录下。不过这些数据类型仅限于不可再生的数据,可再生的数据文件应该存放在Library/Cache目录下。例如,游戏应用可将游戏存档保存在该Documents目录
3、Documents/Inbox(了解)
保存应⽤用运⾏行时⽣生成的需要持久化的数据,iTunes同步设备时会备份该目录。例如,游戏应⽤用可将游戏存档保存在该⽬录 ;该目录还是用来保存由外部应用请求当前应用程序打开的文件。
比如我们的应用叫A,向系统注册了几种可打开的文件格式,B应用有一个A支持的格式文件F,并且申请调用A打开F。由于F当前是在B应用的沙盒中,我们知道,沙盒机制是不允许A访问B沙盒中的文件,因此苹果的解决方案是将F拷贝一份到A应用的Documents/Inbox目录下,再让A打开F。
4、Library 苹果建议用来存放默认设置或其它状态信息。
5、Library/Caches 主要是缓存文件,用户使用过程中缓存都可以保存在这个目录中。保存应⽤运行时⽣成的需要持久化的数据,iTunes同步设备时不会备份该⽬目录。一般存储体积⼤大、不需要备份的⾮重要数据
6、Library/Preferences 保存应⽤用的所有偏好设置。我们使用NSUserDefaults写的设置数据也会保存到该目录下的一个plist文件中!
7、tmp 保存应⽤运⾏时所需的临时数据,使用完毕后再将相应的文件从该⽬目录删除。应⽤没有运⾏时,该目录下的东西随时有可能被系统清理掉,例如:系统磁盘存储空间不足的时候。iPhone在重启时,会丢弃所有的tmp文件。
数组的存取
一)写入到指定的目录
1)第一种方法
NSArray* array = [[NSArray alloc] initWithObjects:@"读",@"写",@"读和写",@"只读",@"读写", nil];
NSString* sandBoxPath = NSHomeDirectory();
NSString* path = [sandBoxPath stringByAppendingPathComponent:@"Documents/54"];
2)第二种方法
NSArray* array = [[NSArray alloc] initWithObjects:@"读",@"写",@"读和写",@"只读",@"读写", nil];
NSString* documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString* path = [documentPath stringByAppendingPathComponent:@"54"];
二)取数据
NSArray* readArray1 = [[NSArray alloc] initWithContentsOfFile:filePath];
NSArray* readArray2 = [NSArray arrayWithContentsOfFile:filePath];
注意:数组中的元素有中文时,打印的结果是编码后的内容,可以使用for循环打印
for (id object in readArray1)
{
NSLog(@"____%@",object);
}
把获取指定目录的文件设置成一个方法直接调用
获取指定目录下的文件
<pre name="code" class="objc">- (NSString *)getFilePath:(NSString *)fileName
{
NSString* filePath = [[self getDocumentPath] stringByAppendingPathComponent:fileName];
return
}
ilePath;
Documents目录路径
- (NSString *)getDocumentPath
{
NSString* documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
return documentPath;
}
注意:writeToFile:写入数据时,多次写入会将之前的内容覆盖掉
字典的写入
NSDictionary* dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"11",@"1",@"22",@"2",@"33",@"3", nil];
NSDictionary* dic = @{@"1": @"11",@"2":@"22",@"3":@"33"};
NSString* filePath2 = [self getFilePath:@"2"];
[dictionary writeToFile:filePath2 atomically:YES];
读取
NSDictionary* readDic1 = [[NSDictionary alloc] initWithContentsOfFile:filePath2];
NSDictionary* readDic2 = [NSDictionary dictionaryWithContentsOfFile:filePath2];
NSLog(@"2____%@___%@",readDic1,readDic2);
字符串的写入
NSString* string = @"字符串的读取";
NSString* filePath3 = [self getFilePath:@"33"];
[string writeToFile:filePath3 atomically:YES encoding:NSUTF8StringEncoding error:nil];
encoding:使用哪种编码格式:UIFT-8 将字符串编码成data
error:存储时的错误信息:nil
读取
NSString* readString1 = [[NSString alloc] initWithContentsOfFile:filePath3 encoding:NSUTF8StringEncoding error:nil];
NSString* readString2 = [NSString stringWithContentsOfFile:filePath3 encoding:NSUTF8StringEncoding error:nil];
NSLog(@"3____%@___%@",readString1,readString2);
NSData 写入
NSString* dataStr = @“123。。。”;
//NSString-->NSData
NSData* data = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
NSString* filePath4 = [self getFilePath:@"datafile"];
[data writeToFile:filePath4 atomically:YES];
读取:
NSData* readData = [[NSData alloc] initWithContentsOfFile:filePath4];
NSData* readData2 = [NSData dataWithContentsOfFile:filePath4];
NSLog(@"___%@___%@",readData,readData2);
[self.window makeKeyAndVisible];
return YES;
}
获取指定目录下的文件
- (NSString *)getFilePath:(NSString *)fileName
{
NSString* filePath = [[self getDocumentPath] stringByAppendingPathComponent:fileName];
return filePath;
}
获取应用沙盒根路径:
-(void)dirHome{
NSString *dirHome=NSHomeDirectory();
NSLog(@"app_home: %@",dirHome);
}
获取Documents目录路径:
(1)拼接:拼接时系统会自动添加一个‘/’;拼接的方式,易出错
NSString* documentPath = [homePath stringByAppendingPathComponent:@"Documents"];
NSLog(@"2.1Document路径——————%@",documentPath);
(2)字符串拼接:
NSString* document2 = [NSString stringWithFormat:@"%@/Documents",homePath];
NSLog(@"2.2____%@",document2);
(3)采用搜索路径:根据指定区域搜索指定文件夹
1.要搜索的文件夹(目录):Document
2.要搜索的区域:NSUserDomainMask当前域(当前根目录及沙盒目录)
3.是否获取全路径(完整路径):使用绝对路径或者相对路径
方法返回值为数组,此数组中第一个路径是要获取的正确路径
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* document3 = paths[0];
NSLog(@"2.3____%@",document3);
获取Library目录路径:
- 获取Library目录
-(void)dirLib{
//[NSHomeDirectory() stringByAppendingPathComponent:@"Library"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libraryDirectory = [paths objectAtIndex:0];
NSLog(@"app_home_lib: %@",libraryDirectory);
}
获取 Cache 目录路径:
- 获取Cache目录
-(void)dirCache{
NSArray *cacPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [cacPath objectAtIndex:0];
NSLog(@"app_home_lib_cache: %@",cachePath);
}
获取Tmp目录路径:
- //获取Tmp目录
-(void)dirTmp{
//[NSHomeDirectory() stringByAppendingPathComponent:@"tmp"];
NSString *tmpDirectory = NSTemporaryDirectory();
NSLog(@"app_home_tmp: %@",tmpDirectory);
}
创建文件夹:
- //创建文件夹
-(void *)createDir{
NSString *documentsPath =[self dirDoc];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
// 创建目录
BOOL res=[fileManager createDirectoryAtPath:testDirectory withIntermediateDirectories:YES attributes:nil error:nil];
if (res) {
NSLog(@"文件夹创建成功");
}else
NSLog(@"文件夹创建失败");
}
创建文件
- //创建文件
-(void *)createFile{
NSString *documentsPath =[self dirDoc];
NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];
BOOL res=[fileManager createFileAtPath:testPath contents:nil attributes:nil];
if (res) {
NSLog(@"文件创建成功: %@" ,testPath);
}else
NSLog(@"文件创建失败");
}
写数据到文件:
- //写文件
-(void)writeFile{
NSString *documentsPath =[self dirDoc];
NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];
NSString *content=@"测试写入内容!";
BOOL res=[content writeToFile:testPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
if (res) {
NSLog(@"文件写入成功");
}else
NSLog(@"文件写入失败");
}
读文件数据:
- //读文件
-(void)readFile{
NSString *documentsPath =[self dirDoc];
NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];
// NSData *data = [NSData dataWithContentsOfFile:testPath];
// NSLog(@"文件读取成功: %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
NSString *content=[NSString stringWithContentsOfFile:testPath encoding:NSUTF8StringEncoding error:nil];
NSLog(@"文件读取成功: %@",content);
}
文件属性:
- //文件属性
-(void)fileAttriutes{
NSString *documentsPath =[self dirDoc];
NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];
NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:testPath error:nil];
NSArray *keys;
id key, value;
keys = [fileAttributes allKeys];
int count = [keys count];
for (int i = 0; i < count; i++)
{
key = [keys objectAtIndex: i];
value = [fileAttributes objectForKey: key];
NSLog (@"Key: %@ for value: %@", key, value);
}
}
删除文件:
- //删除文件
-(void)deleteFile{
NSString *documentsPath =[self dirDoc];
NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];
BOOL res=[fileManager removeItemAtPath:testPath error:nil];
if (res) {
NSLog(@"文件删除成功");
}else
NSLog(@"文件删除失败");
NSLog(@"文件是否存在: %@",[fileManager isExecutableFileAtPath:testPath]?@"YES":@"NO");
}