【IOS开发基础系列 整理】IOS沙盒机制专题

整理自如下文章:

iOS学习之iOS沙盒(sandbox)机制和文件操作(一)

http://blog.csdn.net/totogo2010/article/details/7669837

iOS学习之iOS沙盒(sandbox)机制和文件操作(二)

http://blog.csdn.net/totogo2010/article/details/7670417

iOS学习之iOS沙盒(sandbox)机制和文件操作之NSFileManager(三)

http://blog.csdn.net/totogo2010/article/details/7671144


1 IOS沙盒(sandbox)机制原理

1.1 IOS沙盒机制

    IOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文本文件等。

    1、每个应用程序都有自己的存储空间

    2、应用程序不能翻过自己的围墙去访问别的存储空间的内容

    3、应用程序请求的数据都要通过权限检测,假如不符合条件的话,不会被放行。通过这张图只能从表层上理解sandbox是一种安全体系,应用程序的所有操作都要通过这个体系来执行,其中核心内容是:sandbox对应用程序执行各种操作的权限限制。

1.2 打开模拟器沙盒目录

        下面看看模拟器的沙盒文件夹在mac电脑上的什么位置。

        文件都在个人用户名文件夹下的一个隐藏文件夹里,中文叫资源库,他的目录其实是Library。

        2.1 方法1、可以设置显示隐藏文件,然后在Finder下直接打开。设置查看隐藏文件的方法如下:打开终端,输入命名

显示Mac隐藏文件的命令:defaults  write com.apple.finder AppleShowAllFiles -bool true

隐藏Mac隐藏文件的命令:defaults  write com.apple.finder AppleShowAllFiles -bool false

        输完单击Enter键,退出终端,重新启动Finder就可以了 重启Finder:鼠标单击窗口左上角的苹果标志-->强制退出-->Finder-->

现在能看到资源库文件夹了。

        打开资源库后找到/Application Support/iPhone Simulator/文件夹。这里面就是模拟器的各个程序的沙盒目录了。

        2.2 方法2、这种方法更方便,在Finder上点->前往->前往文件夹,输入 /Users/username/Library/Application Support/iPhone Simulator/  前往。

username这里写你的用户名。

2 读取各目录结构

        默认情况下,每个沙盒含有3个文件夹:Documents, Library 和 tmp。因为应用的沙盒机制,应用只能在几个目录下读写文件

        Documents:苹果建议将程序中建立的或在程序中浏览到的文件数据保存在该目录下,iTunes备份和恢复的时候会包括此目录

        Library:存储程序的默认设置或其它状态信息;

        Library/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除

        tmp:提供一个即时创建临时文件的地方。


        iTunes在与iPhone同步时,备份所有的Documents和Library文件。iPhone在重启时,会丢弃所有的tmp文件。

        我们创建一个IosSandbox的项目来展开沙盒和文件读写等操作的练习。创建后找到模拟器上对应的目录,这是目录全展开了。

        这是上面提到的三个目录 :Documents、Library、tmp

2.1 获取程序的Home目录

NSArray *paths =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,  YES);

NSString *path =  [paths objectAtIndex:0];

NSLog(@"path:%@",  path);

打印结果:

2012-06-17  14:00:06.098 IosSandbox[3536:f803] /Users/rongfzh/Library/Application  Support/iPhone  Simulator/5.1/Applications/3B8EC78A-5EEE-4C2F-B0CB-4C3F02B996D2


        那在真机上的目录有是怎么样的呢?我们看看

2012-06-17 14:25:47.059  IosSandbox[4281:f803]  /var/mobile/Applications/3B8EC78A-5EEE-4C2F-B0CB-4C3F02B996D2

        可见,真机上的目录是/var/mobile/Applications/这个目录下的,和模拟器不一样。这个是Home目录,其他的子目录和模拟器一样。

2.2 获取document目录

NSArray *paths =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,  YES);

NSString *path =  [paths objectAtIndex:0];

NSLog(@"path:%@",  path);

打印结果

2012-06-17  14:00:06.099 IosSandbox[3536:f803] path:/Users/rongfzh/Library/Application  Support/iPhone  Simulator/5.1/Applications/3B8EC78A-5EEE-4C2F-B0CB-4C3F02B996D2/Documents

2.3 获取Cache目录[cpp]view plaincopy

NSArray *paths =  NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask,  YES);

NSString *path =  [paths objectAtIndex:0];

NSLog(@"%@",  path);

打印结果

2012-06-17  14:03:50.431 IosSandbox[3628:f803] /Users/rongfzh/Library/Application  Support/iPhone  Simulator/5.1/Applications/3B8EC78A-5EEE-4C2F-B0CB-4C3F02B996D2/Library/Caches

2.4 获取Library目录[cpp]view plaincopy

NSArray *paths =  NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask,  YES);

NSString *path =  [paths objectAtIndex:0];

NSLog(@"%@",  path);

打印结果[cpp]view plaincopy

2012-06-17  14:07:17.544 IosSandbox[3733:f803] /Users/rongfzh/Library/Application  Support/iPhone  Simulator/5.1/Applications/3B8EC78A-5EEE-4C2F-B0CB-4C3F02B996D2/Library

2.5 获取Tmp目录[cpp]view plaincopy

NSString *tmpDir  = NSTemporaryDirectory();

NSLog(@"%@",  tmpDir);

打印结果[cpp]view plaincopy

2012-06-17  14:08:07.824 IosSandbox[3782:f803]  /var/folders/g7/246bh79130zblw0yjjtc55cw0000gn/T/

2.6 写入文件[cpp]view plaincopy

NSArray *paths =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,  YES);

NSString *docDir = [paths objectAtIndex:0];

if  (!docDir) { 

        NSLog(@"Documents 目录未找到");

NSArray *array = [[NSArray alloc] initWithObjects:@"内容",@"content",nil];

NSString *filePath = [docDir  stringByAppendingPathComponent:@"testFile.txt"];

[array writeToFile:filePath atomically:YES];


注:我们在真机上也运行一下,把文件写入,下一步从真机上把内容读取出来。

写入array ,里面是两个字符串,一会我们读出来打印。

写入我们在程序沙盒目录下看到文件testFile.txt

        打开文件看到的内容是这样的,是个xml格式的plist文件,数据格式保存了内容。

2.7 读取文件

NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

NSString *docDir = [pathsobjectAtIndex:0];

NSString *filePath = [docDirstringByAppendingPathComponent:@"testFile.txt"];

NSArray *array = [[NSArrayalloc]initWithContentsOfFile:filePath];

NSLog(@"%@", array);

        打印结果,把上面的文件解析后,把内容打印出来了。

2012-06-17 14:14:46.249 IosSandbox[3918:f803] (

    "\U5185\U5bb9",

    content

)


        真机上读取并打印文件路径:

2012-06-17 14:25:47.059  IosSandbox[4281:f803]  /var/mobile/Applications/3B8EC78A-5EEE-4C2F-B0CB-4C3F02B996D2/Documents/testFile.txt

(

    "\U5185\U5bb9",

    content

)

        真机上也能写入和打印。

3. 文件操作

        我们看看NSFileManager如何使用。包括创建文件,目录,删除,遍历目录等。

3.1 在Documents里创建目录

        创建一个叫test的目录,先找到Documents的目录,

NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

NSString *documentsDirectory =[paths objectAtIndex:0];

NSLog(@"documentsDirectory%@",documentsDirectory);

NSFileManager *fileManager =[NSFileManager defaultManager];

NSString *testDirectory =[documentsDirectory stringByAppendingPathComponent:@"test"];

   // 创建目录

[fileManagercreateDirectoryAtPath:testDirectory withIntermediateDirectories:YESattributes:nil error:nil];

        启动程序,这时候目录就创建了:


3.2 在test目录下创建文件

        创建文件怎么办呢?接着上面的代码 testPath 要用stringByAppendingPathComponent拼接上你要生成的文件名,比如test00.txt。这样才能在test下写入文件。

        testDirectory是上面代码生成的路径哦,不要忘了。我往test文件夹里写入三个文件,test00.txt ,test22.txt,text.33.txt。内容都是写入内容,write String。

实现代码如下:

NSString *testPath = [testDirectorystringByAppendingPathComponent:@"test00.txt"];

NSString *testPath2 = [testDirectorystringByAppendingPathComponent:@"test22.txt"];

NSString *testPath3 = [testDirectorystringByAppendingPathComponent:@"test33.txt"];

NSString *string = @"写入内容,write String";

[fileManager createFileAtPath:testPathcontents:[string  dataUsingEncoding:NSUTF8StringEncoding]attributes:nil];

[fileManager createFileAtPath:testPath2contents:[string  dataUsingEncoding:NSUTF8StringEncoding]attributes:nil];

[fileManager createFileAtPath:testPath3contents:[string  dataUsingEncoding:NSUTF8StringEncoding]attributes:nil];

        看下面的图,三个文件都出来了,内容也对。

        在Documents目录下创建就更简单了,不用加test就ok了

3.3 获取目录列里所有文件名

        两种方法获取:subpathsOfDirectoryAtPath和subpathsAtPath

NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

NSString *documentsDirectory = [pathsobjectAtIndex:0];

NSLog(@"documentsDirectory%@",documentsDirectory);

NSFileManager *fileManage = [NSFileManagerdefaultManager];

NSString *myDirectory = [documentsDirectorystringByAppendingPathComponent:@"test"];

NSArray *file = [fileManagesubpathsOfDirectoryAtPath: myDirectory error:nil];

NSLog(@"%@",file);

NSArray *files = [fileManage subpathsAtPath:myDirectory ];

NSLog(@"%@",files);

        获取上面刚才test文件夹里的文件名

打印结果

2012-06-17  23:23:19.684 IosSandbox[947:f803] fileList:(

    ".DS_Store",

    "test00.txt",

    "test22.txt",

    "test33.txt"

)

2012-06-17  23:23:19.686 IosSandbox[947:f803] fileLit(

    ".DS_Store",

    "test00.txt",

    "test22.txt",

    "test33.txt"

)

        两个方法都可以,隐藏的文件也打印出来了。

3.4 fileManager使用操作当前目录

//创建文件管理器

NSFileManager *fileManager =[NSFileManager defaultManager];

NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

NSString *documentsDirectory =[paths objectAtIndex:0];

//更改到待操作的目录下

[fileManagerchangeCurrentDirectoryPath:[documentsDirectory stringByExpandingTildeInPath]];

//创建文件fileName文件名称,contents文件的内容,如果开始没有内容可以设置为nil,attributes文件的属性,初始为nil

NSString * fileName =@"testFileNSFileManager.txt";

NSArray *array = [[NSArrayalloc] initWithObjects:@"hello world",@"hello world1",@"hello world2",nil];

[fileManager createFileAtPath: fileName contents: array attributes: nil];

        这样就创建了testFileNSFileManager.txt并把三个hello world写入文件了

        changeCurrentDirectoryPath目录更改到当前操作目录时,做文件读写就很方便了,不用加上全路径

3.5 删除文件

        接上面的代码,remove就ok了。

[fileManager  removeItemAtPath:fileName error:nil];

3.6 混合数据的读写

        用NSMutableData创建混合数据,然后写到文件里。并按数据的类型把数据读出来

3.6.1 写入数据

NSString * fileName =@"testFileNSFileManager.txt";

NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

NSString *documentsDirectory = [pathsobjectAtIndex:0];

//获取文件路径

NSString *path = [documentsDirectorystringByAppendingPathComponent:fileName];

//待写入的数据

NSString *temp = @"nihao 世界";

int dataInt = 1234;

float dataFloat = 3.14f;

//创建数据缓冲

NSMutableData *writer = [[NSMutableDataalloc] init];

//将字符串添加到缓冲中

[writer appendData: [temp dataUsingEncoding: NSUTF8StringEncoding]];

//将其他数据添加到缓冲中

[writer appendBytes: &dataInt length: sizeof(dataInt)];

[writer appendBytes:&dataFloat length: sizeof(dataFloat)];

//将缓冲的数据写入到文件中

[writer writeToFile: path atomically:YES];

我们看看数据怎么样了:

        我们看到后面的是乱码,那是中文被转成了NSData后,还有int float的二进制

3.6.2 读取刚才写入的数据

//读取数据:

int intData;

float floatData = 0.0;

NSString *stringData;

NSData *reader = [NSData dataWithContentsOfFile: path];

stringData = [[NSString alloc] initWithData: [reader subdataWithRange: NSMakeRange(0, [temp length])] encoding: NSUTF8StringEncoding];

[reader getBytes: &intData range: NSMakeRange([temp length], sizeof(intData))];

[reader getBytes: &floatData range: NSMakeRange([temp length] + sizeof(intData), sizeof(floatData))];

 NSLog(@"stringData: %@ intData: %d floatData: %f", stringData, intData, floatData);

        打印出来的结果:

2012-06-17  23:51:14.723 IosSandbox[1285:f803] stringData:nihao hello! intData:1234332  floatData:3.140000

        这里把写入的汉字改成了hello。因为[temp length]算长度是,把中文算成一位了,出来的结果有误。

4. 参考链接

iOS学习7:iOS沙盒(sandBox)机制(一)之获取沙盒路径及目录说明

http://my.oschina.net/joanfen/blog/151145

iOS学习之iOS沙盒(sandbox)机制和文件操作(一)

http://blog.csdn.net/totogo2010/article/details/7669837

iOS学习之iOS沙盒(sandbox)机制和文件操作(二)

http://blog.csdn.net/totogo2010/article/details/7670417

iOS学习之iOS沙盒(sandbox)机制和文件操作之NSFileManager(三)

http://blog.csdn.net/totogo2010/article/details/7671144

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

推荐阅读更多精彩内容