沙盒機(jī)制
處于安全考慮,iOS系統(tǒng)的沙盒機(jī)制規(guī)定每個(gè)應(yīng)用都只能訪問(wèn)當(dāng)前沙盒目錄下面的文件(也有例外真慢,比如在用戶授權(quán)情況下訪問(wèn)通訊錄灾挨,相冊(cè)等),這個(gè)規(guī)則展示了iOS系統(tǒng)的封閉性继低。在開(kāi)發(fā)中常常需要數(shù)據(jù)存儲(chǔ)的功能熬苍,比如存取文件,歸檔解檔等。
打個(gè)廣告:問(wèn)題驗(yàn)證demo里有相關(guān)的驗(yàn)證柴底,可以去看看
沙盒的機(jī)構(gòu)目錄:
截取自蘋(píng)果官方文檔(File System Basics)
截取自官方文檔——常用目錄說(shuō)明
文件目錄分類:
-
應(yīng)用程序包
就是存放應(yīng)用源文件婿脸,包含:
- 資源文件
- 可執(zhí)行文件
-
Documents
最常用的目錄,適合存儲(chǔ)重要數(shù)據(jù)柄驻。iTunes會(huì)同步此內(nèi)容
-
Library
-
Caches
應(yīng)用程序用于備份非重要的數(shù)據(jù)狐树。iTunes不會(huì)同步
-
Preferences(plist)
通常用于保存應(yīng)用的設(shè)置信息。iTunes會(huì)同步此內(nèi)容
(其他自定義的文件夾)
-
-
tmp
此目錄適合保存應(yīng)用中的一些臨時(shí)文件鸿脓,用完就會(huì)刪除抑钟。*系統(tǒng)可能在應(yīng)用沒(méi)運(yùn)行時(shí)就刪除該目錄下的文件
臨時(shí)文件應(yīng)該放哪里呢?
app存儲(chǔ)大文件到iTunes和iCloud會(huì)減慢備份進(jìn)程野哭,這些應(yīng)用也會(huì)消耗用戶大量備份空間在塔,這會(huì)導(dǎo)致用戶刪除你的app,或禁用該app的備份數(shù)據(jù)到iCloud功能虐拓。為減少同步和備份進(jìn)程占用太長(zhǎng)時(shí)間心俗,文件存儲(chǔ)要放在合適位置。因此蓉驹,應(yīng)該按照以下準(zhǔn)則選擇文件位置:
將用戶數(shù)據(jù)放入Documents/:
用戶數(shù)據(jù)通常包括您可能想要向用戶公開(kāi)的任何文件城榛,這些文件可以由用戶創(chuàng)建、導(dǎo)入态兴、刪除或編輯狠持。對(duì)于繪圖應(yīng)用,用戶數(shù)據(jù)包括用戶創(chuàng)建的任何圖形文件瞻润;對(duì)于文本編輯器喘垂,包括用戶創(chuàng)建的文本文件;對(duì)于音視頻應(yīng)用绍撞,包括用戶下載以便稍后觀看或收聽(tīng)的文件正勒。將應(yīng)用創(chuàng)建的支持文件放在Library/Application support/目錄中:
一般,此目錄的文件用于支持app運(yùn)行傻铣,同時(shí)不應(yīng)該被用戶接觸章贞。該目錄還可以包括數(shù)據(jù)文件、配置文件非洲、模板以及從應(yīng)用程序包中加載資源的修改版本鸭限。把臨時(shí)數(shù)據(jù)放在tmp/目錄:
臨時(shí)數(shù)據(jù)包括任何不需要長(zhǎng)時(shí)間保留的數(shù)據(jù),在不需要這些數(shù)據(jù)時(shí)記得刪除它們两踏,以便不再占用用戶設(shè)備空間败京。在app未運(yùn)行時(shí),系統(tǒng)會(huì)定期清除這些文件梦染。因此赡麦,任何需要長(zhǎng)期使用的數(shù)據(jù)都不能放在tmp/目錄。把數(shù)據(jù)緩存文件放在Library/Caches/目錄:
數(shù)據(jù)緩存文件保存時(shí)間比臨時(shí)數(shù)據(jù)長(zhǎng),但沒(méi)有Application Support持久隧甚。一般來(lái)說(shuō)车荔,沒(méi)有緩存數(shù)據(jù)程序也可以正常運(yùn)行,但有了緩存數(shù)據(jù)可以提高性能戚扳。緩存數(shù)據(jù)包括但不限于數(shù)據(jù)庫(kù)緩存文件忧便、可下載文件等。系統(tǒng)可能會(huì)刪除Caches/目錄的內(nèi)容以釋放磁盤(pán)空間帽借,因此珠增,你的app必須能夠根據(jù)需要重新創(chuàng)建或下載這些文件。
關(guān)于臨時(shí)數(shù)據(jù)是否需要被iCloud備份砍艾,是可以通過(guò)[NSURL setResourceValue: forKey: error: ]方法排除不需要備份的文件:
iCloud默認(rèn)會(huì)對(duì)Documents/和Application Support/目錄內(nèi)容進(jìn)行備份蒂教,可以通過(guò)[NSURL setResourceValue: forKey: error: ]方法排除不需要備份的文件,此時(shí)key應(yīng)為NSURLIsExcludedFromBackupKey脆荷。任何可以被再次創(chuàng)建或下載的文件都必須從備份中排出凝垛,這對(duì)于大型媒體文件尤為重要。如果你的app需要下載音頻或視頻蜓谋,一定要把下載的音視頻從備份中排除梦皮。
總結(jié)下各位置的使用場(chǎng)景:
- 如果我們想要長(zhǎng)期持有某文件的保存,請(qǐng)使用
Documents
-
Preferences(plist)
一般存放的時(shí)候工程plist
文件桃焕,我們一般不去動(dòng)此文件件 - cache與tmp的作用類型剑肯,但是可能tmp的生命周期比cache會(huì)更短,app內(nèi)不重要的內(nèi)容观堂,都可以放置在這兩個(gè)文件夾让网,可以視文件重要性而定
p.s. 存取刪查相關(guān)操作
各個(gè)文件路徑的獲取
// 獲取沙盒主目錄路徑
NSString *homeDir = NSHomeDirectory();
// 獲取Documents目錄路徑
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
// 獲取Library的目錄路徑
NSString *libDir = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
// 獲取Caches目錄路徑
NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
// 獲取tmp目錄路徑
NSString *tmpDir = NSTemporaryDirectory();
創(chuàng)建相關(guān)文件夾或文件
使用stringByAppendingPathComponent
增加文件路徑
如果此路徑不存在,可以為其創(chuàng)建师痕。如下所示:
NSString *tmpDir = NSTemporaryDirectory();
NSString *logDirectory = [tmpDir stringByAppendingPathComponent:@"carSealDoc"];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL fileExists = [fileManager fileExistsAtPath:logDirectory];
if (!fileExists) {
NSError *error = nil;
[fileManager createDirectoryAtPath:logDirectory withIntermediateDirectories:YES attributes:nil error:&error];
if (error) {
NSLog(@"error = %@",[error localizedDescription]);
}
}
判斷文件是否存在
將使用到NSFileManager
類來(lái)做文件尋找
// 判讀緩存數(shù)據(jù)是否存在
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:@"string"]) {
// 讀取緩存數(shù)據(jù)
NSData *returnData = [NSData dataWithContentsOfFile:@"string"];
}else{
NSLog(@"nofile");
}
清除文件夾或文件
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *tmpDir = NSTemporaryDirectory();
NSDirectoryEnumerator *fileEnumerator = [fileManager enumeratorAtPath:tmpDir];
for (NSString *fileName in fileEnumerator) {
NSString *filePath = [tmpDir stringByAppendingPathComponent:fileName];
[fileManager removeItemAtPath:filePath error:nil];
}
如果需要單獨(dú)刪除某一文件溃睹,將path換成文件路徑即可