** 引言 **
iOS中的沙盒機(jī)制是一種安全體系, 規(guī)定了應(yīng)用程序只能在為該改程序創(chuàng)建的文件中讀取文件,不可以去其它地方訪(fǎng)問(wèn)尤溜,此區(qū)域被成為沙盒。
所有的非代碼文件都要保存在自己的沙盒中汗唱,例如圖像宫莱,圖標(biāo),聲音哩罪,映像授霸,屬性列表,文本文件等际插。
I. 沙盒機(jī)制
- 每個(gè)應(yīng)用程序都有自己的存儲(chǔ)空間
- 應(yīng)用程序不能翻過(guò)自己的圍墻去訪(fǎng)問(wèn)別的存儲(chǔ)空間的內(nèi)容
- 應(yīng)用程序請(qǐng)求的數(shù)據(jù)都要通過(guò)權(quán)限檢測(cè)碘耳,假如不符合條件的話(huà),不會(huì)被放行框弛。
通過(guò)這張圖只能從表層上理解sandbox是一種安全體系辛辨,應(yīng)用程序的所有操作都要通過(guò)這個(gè)體系來(lái)執(zhí)行,其中核心內(nèi)容是:sandbox對(duì)應(yīng)用程序執(zhí)行各種操作的權(quán)限限制功咒。
II. 目錄結(jié)構(gòu)
因?yàn)閼?yīng)用的沙盒機(jī)制愉阎,應(yīng)用只能在以下幾個(gè)目錄下讀寫(xiě)文件。默認(rèn)情況下力奋,每個(gè)沙盒含有3個(gè)文件夾:Documents
, Library
和 tmp
:
每個(gè)應(yīng)用的沙盒目錄都是相似的榜旦,主要包含圖中所示的4個(gè)目錄:
1、MyApp.app
① 存放內(nèi)容
該目錄包含了應(yīng)用程序本身的數(shù)據(jù)景殷,包括資源文件和可執(zhí)行文件等溅呢。程序啟動(dòng)以后澡屡,會(huì)根據(jù)需要從該目錄中動(dòng)態(tài)加載代碼或資源到內(nèi)存,這里用到了lazy loading的思想咐旧。
② 整個(gè)目錄是只讀的
為了防止被篡改驶鹉,應(yīng)用在安裝的時(shí)候會(huì)將該目錄簽名。非越獄情況下铣墨,該目錄中內(nèi)容是無(wú)法更改的室埋;在越獄設(shè)備上如果更改了目錄內(nèi)容,對(duì)應(yīng)的簽名就會(huì)被改變伊约,這種情況下蘋(píng)果官網(wǎng)描述的后果是應(yīng)用程序?qū)o(wú)法啟動(dòng)姚淆,我沒(méi)實(shí)踐過(guò)。
③ 是否會(huì)被iTunes同步
否
2屡律、Documents
① 存放內(nèi)容
我們可以將應(yīng)用程序的數(shù)據(jù)文件保存在該目錄下腌逢。不過(guò)這些數(shù)據(jù)類(lèi)型僅限于不可再生的數(shù)據(jù),可再生的數(shù)據(jù)文件應(yīng)該存放在Library/Cache目錄下超埋。
② 是否會(huì)被iTunes同步
是
3搏讶、Documents/Inbox
① 存放內(nèi)容
該目錄用來(lái)保存由外部應(yīng)用請(qǐng)求當(dāng)前應(yīng)用程序打開(kāi)的文件。
比如我們的應(yīng)用叫A霍殴,向系統(tǒng)注冊(cè)了幾種可打開(kāi)的文件格式媒惕,B應(yīng)用有一個(gè)A支持的格式的文件F,并且申請(qǐng)調(diào)用A打開(kāi)F来庭。由于F當(dāng)前是在B應(yīng)用的沙盒中吓笙,我們知道,沙盒機(jī)制是不允許A訪(fǎng)問(wèn)B沙盒中的文件巾腕,因此蘋(píng)果的解決方案是講F拷貝一份到A應(yīng)用的Documents/Inbox目錄下面睛,再讓A打開(kāi)F。
② 是否會(huì)被iTunes同步
是
4尊搬、Library
① 存放內(nèi)容
蘋(píng)果建議用來(lái)存放默認(rèn)設(shè)置或其它狀態(tài)信息叁鉴。
② 是否會(huì)被iTunes同步
是,但是要除了Caches子目錄外
5佛寿、Library/Caches
① 存放內(nèi)容
主要是緩存文件幌墓,用戶(hù)使用過(guò)程中緩存都可以保存在這個(gè)目錄中。前面說(shuō)過(guò)冀泻,Documents目錄用于保存不可再生的文件常侣,那么這個(gè)目錄就用于保存那些可再生的文件,比如網(wǎng)絡(luò)請(qǐng)求的數(shù)據(jù)弹渔。鑒于此胳施,應(yīng)用程序通常還需要負(fù)責(zé)刪除這些文件。
② 是否會(huì)被iTunes同步
否
6肢专、Library/Preferences
① 存放內(nèi)容
應(yīng)用程序的偏好設(shè)置文件舞肆。我們使用NSUserDefaults寫(xiě)的設(shè)置數(shù)據(jù)都會(huì)保存到該目錄下的一個(gè)plist文件中焦辅,這就是所謂的寫(xiě)道plist中!
② 是否會(huì)被iTunes同步
是
7椿胯、tmp
① 存放內(nèi)容
各種臨時(shí)文件筷登,保存應(yīng)用再次啟動(dòng)時(shí)不需要的文件。而且哩盲,當(dāng)應(yīng)用不再需要這些文件時(shí)應(yīng)該主動(dòng)將其刪除前方,因?yàn)樵撃夸浵碌臇|西隨時(shí)有可能被系統(tǒng)清理掉,目前已知的一種可能清理的原因是系統(tǒng)磁盤(pán)存儲(chǔ)空間不足的時(shí)候廉油。
② 是否會(huì)被iTunes同步
否
iTunes在與iPhone同步時(shí)镣丑,備份所有的Documents和Library文件。
iPhone在重啟時(shí)娱两,會(huì)丟棄所有的tmp文件。
III. 代碼獲取文件夾路徑
獲取根目錄:
// 獲取根目錄
NSString *homePath = NSHomeDirectory();
NSLog(@"Home目錄:%@",homePath);
獲取Documents文件夾目錄:
NSArray *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsPath = [docPath objectAtIndex:0];
NSLog(@"Documents目錄:%@",documentsPath);
獲取Library文件夾目錄:
NSArray *libsPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libPath = [libsPath objectAtIndex:0];
NSLog(@"Library目錄:%@",libPath);
獲取Cache文件夾目錄:
NSArray *cacPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [cacPath objectAtIndex:0];
NSLog(@"Cache目錄:%@",cachePath);
獲取tmp目錄:
//temp目錄
NSString *tempPath = NSTemporaryDirectory();
NSLog(@"temp目錄:%@",tempPath);
IV. 沙盒讀寫(xiě)文件
向沙盒中寫(xiě)入文件:
NSArray *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsPath = [docPath objectAtIndex:0];
//寫(xiě)入文件
if (!documentsPath) {
NSLog(@"目錄未找到");
}else {
NSString *filePaht = [documentsPath stringByAppendingPathComponent:@"test.txt"];
NSArray *array = [NSArray arrayWithObjects:@"Title",@"Contents", nil];
[array writeToFile:filePaht atomically:YES];
}
向沙盒中寫(xiě)入文件:
//讀取文件
NSArray *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsPath = [docPath objectAtIndex:0];
NSString *readPath = [documentsPath stringByAppendingPathComponent:@"test.txt"];
// 寫(xiě)入的什么類(lèi)型的數(shù)據(jù) 就要用這個(gè)類(lèi)型來(lái)讀取
NSArray *fileContent = [[NSArray alloc] initWithContentsOfFile:readPath];
NSLog(@"文件內(nèi)容:%@",fileContent);