整理自如下文章:
iOS學(xué)習(xí)之iOS沙盒(sandbox)機(jī)制和文件操作(一)
http://blog.csdn.net/totogo2010/article/details/7669837
iOS學(xué)習(xí)之iOS沙盒(sandbox)機(jī)制和文件操作(二)
http://blog.csdn.net/totogo2010/article/details/7670417
iOS學(xué)習(xí)之iOS沙盒(sandbox)機(jī)制和文件操作之NSFileManager(三)
http://blog.csdn.net/totogo2010/article/details/7671144
1 IOS沙盒(sandbox)機(jī)制原理
1.1 IOS沙盒機(jī)制
????IOS應(yīng)用程序只能在為該改程序創(chuàng)建的文件系統(tǒng)中讀取文件阅畴,不可以去其它地方訪(fǎng)問(wèn),此區(qū)域被成為沙盒驱显,所以所有的非代碼文件都要保存在此矛市,例如圖像鳖擒,圖標(biāo),聲音,映像,屬性列表赵誓,文本文件等。
????1柿赊、每個(gè)應(yīng)用程序都有自己的存儲(chǔ)空間
????2俩功、應(yīng)用程序不能翻過(guò)自己的圍墻去訪(fǎng)問(wèn)別的存儲(chǔ)空間的內(nèi)容
????3、應(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)限限制。
1.2 打開(kāi)模擬器沙盒目錄
????????下面看看模擬器的沙盒文件夾在mac電腦上的什么位置瞻颂。
????????文件都在個(gè)人用戶(hù)名文件夾下的一個(gè)隱藏文件夾里豺谈,中文叫資源庫(kù)茬末,他的目錄其實(shí)是Library吐根。
????????2.1 方法1冗疮、可以設(shè)置顯示隱藏文件,然后在Finder下直接打開(kāi)拔妥。設(shè)置查看隱藏文件的方法如下:打開(kāi)終端硬纤,輸入命名
顯示Mac隱藏文件的命令:defaults? write com.apple.finder AppleShowAllFiles -bool true
隱藏Mac隱藏文件的命令:defaults? write com.apple.finder AppleShowAllFiles -bool false
????????輸完單擊Enter鍵逸邦,退出終端桥狡,重新啟動(dòng)Finder就可以了 重啟Finder:鼠標(biāo)單擊窗口左上角的蘋(píng)果標(biāo)志-->強(qiáng)制退出-->Finder-->
現(xiàn)在能看到資源庫(kù)文件夾了。
????????打開(kāi)資源庫(kù)后找到/Application Support/iPhone Simulator/文件夾颅和。這里面就是模擬器的各個(gè)程序的沙盒目錄了。
????????2.2 方法2缕允、這種方法更方便峡扩,在Finder上點(diǎn)->前往->前往文件夾,輸入 /Users/username/Library/Application Support/iPhone Simulator/??前往障本。
username這里寫(xiě)你的用戶(hù)名教届。
2 讀取各目錄結(jié)構(gòu)
????????默認(rèn)情況下,每個(gè)沙盒含有3個(gè)文件夾:Documents, Library 和 tmp驾霜。因?yàn)閼?yīng)用的沙盒機(jī)制巍佑,應(yīng)用只能在幾個(gè)目錄下讀寫(xiě)文件
????????Documents:蘋(píng)果建議將程序中建立的或在程序中瀏覽到的文件數(shù)據(jù)保存在該目錄下,iTunes備份和恢復(fù)的時(shí)候會(huì)包括此目錄
????????Library:存儲(chǔ)程序的默認(rèn)設(shè)置或其它狀態(tài)信息寄悯;
????????Library/Caches:存放緩存文件,iTunes不會(huì)備份此目錄堕义,此目錄下文件不會(huì)在應(yīng)用退出刪除
????????tmp:提供一個(gè)即時(shí)創(chuàng)建臨時(shí)文件的地方猜旬。
????????iTunes在與iPhone同步時(shí),備份所有的Documents和Library文件倦卖。iPhone在重啟時(shí)洒擦,會(huì)丟棄所有的tmp文件。
????????我們創(chuàng)建一個(gè)IosSandbox的項(xiàng)目來(lái)展開(kāi)沙盒和文件讀寫(xiě)等操作的練習(xí)怕膛。創(chuàng)建后找到模擬器上對(duì)應(yīng)的目錄熟嫩,這是目錄全展開(kāi)了。
????????這是上面提到的三個(gè)目錄 :Documents褐捻、Library掸茅、tmp
2.1 獲取程序的Home目錄
NSArray *paths =? NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,? YES);
NSString *path =? [paths objectAtIndex:0];
NSLog(@"path:%@",? path);
打印結(jié)果:
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
????????那在真機(jī)上的目錄有是怎么樣的呢?我們看看
2012-06-17 14:25:47.059? IosSandbox[4281:f803]? /var/mobile/Applications/3B8EC78A-5EEE-4C2F-B0CB-4C3F02B996D2
????????可見(jiàn)柠逞,真機(jī)上的目錄是/var/mobile/Applications/這個(gè)目錄下的昧狮,和模擬器不一樣。這個(gè)是Home目錄板壮,其他的子目錄和模擬器一樣逗鸣。
2.2 獲取document目錄
NSArray *paths =? NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,? YES);
NSString *path =? [paths objectAtIndex:0];
NSLog(@"path:%@",? path);
打印結(jié)果
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);
打印結(jié)果
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);
打印結(jié)果[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);
打印結(jié)果[cpp]view plaincopy
2012-06-17? 14:08:07.824 IosSandbox[3782:f803]? /var/folders/g7/246bh79130zblw0yjjtc55cw0000gn/T/
2.6 寫(xiě)入文件[cpp]view plaincopy
NSArray *paths =? NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,? YES);
NSString *docDir = [paths objectAtIndex:0];
if? (!docDir) {?
? ?? ???NSLog(@"Documents 目錄未找到");
}?
NSArray *array = [[NSArray alloc] initWithObjects:@"內(nèi)容",@"content",nil];
NSString *filePath = [docDir? stringByAppendingPathComponent:@"testFile.txt"];
[array writeToFile:filePath atomically:YES];
注:我們?cè)谡鏅C(jī)上也運(yùn)行一下,把文件寫(xiě)入,下一步從真機(jī)上把內(nèi)容讀取出來(lái)撒璧。
寫(xiě)入array ,里面是兩個(gè)字符串透葛,一會(huì)我們讀出來(lái)打印。
寫(xiě)入我們?cè)诔绦蛏澈心夸浵驴吹轿募estFile.txt
????????打開(kāi)文件看到的內(nèi)容是這樣的,是個(gè)xml格式的plist文件卿樱,數(shù)據(jù)格式保存了內(nèi)容僚害。
2.7 讀取文件
NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *docDir = [pathsobjectAtIndex:0];
NSString *filePath = [docDirstringByAppendingPathComponent:@"testFile.txt"];
NSArray *array = [[NSArrayalloc]initWithContentsOfFile:filePath];
NSLog(@"%@", array);
????????打印結(jié)果,把上面的文件解析后殿如,把內(nèi)容打印出來(lái)了贡珊。
2012-06-17 14:14:46.249 IosSandbox[3918:f803] (
????"\U5185\U5bb9",
????content
)
????????真機(jī)上讀取并打印文件路徑:
2012-06-17 14:25:47.059? IosSandbox[4281:f803]? /var/mobile/Applications/3B8EC78A-5EEE-4C2F-B0CB-4C3F02B996D2/Documents/testFile.txt
(
????"\U5185\U5bb9",
????content
)
????????真機(jī)上也能寫(xiě)入和打印。
3. 文件操作
????????我們看看NSFileManager如何使用涉馁。包括創(chuàng)建文件门岔,目錄,刪除烤送,遍歷目錄等寒随。
3.1 在Documents里創(chuàng)建目錄
????????創(chuàng)建一個(gè)叫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"];
? ?// 創(chuàng)建目錄
[fileManagercreateDirectoryAtPath:testDirectory withIntermediateDirectories:YESattributes:nil error:nil];
????????啟動(dòng)程序帮坚,這時(shí)候目錄就創(chuàng)建了:
3.2 在test目錄下創(chuàng)建文件
????????創(chuàng)建文件怎么辦呢妻往?接著上面的代碼 testPath 要用stringByAppendingPathComponent拼接上你要生成的文件名,比如test00.txt试和。這樣才能在test下寫(xiě)入文件讯泣。
????????testDirectory是上面代碼生成的路徑哦,不要忘了阅悍。我往test文件夾里寫(xiě)入三個(gè)文件好渠,test00.txt ,test22.txt,text.33.txt。內(nèi)容都是寫(xiě)入內(nèi)容节视,write String拳锚。
實(shí)現(xiàn)代碼如下:
NSString *testPath = [testDirectorystringByAppendingPathComponent:@"test00.txt"];
NSString *testPath2 = [testDirectorystringByAppendingPathComponent:@"test22.txt"];
NSString *testPath3 = [testDirectorystringByAppendingPathComponent:@"test33.txt"];
NSString *string = @"寫(xiě)入內(nèi)容,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];
????????看下面的圖寻行,三個(gè)文件都出來(lái)了霍掺,內(nèi)容也對(duì)。
????????在Documents目錄下創(chuàng)建就更簡(jiǎn)單了拌蜘,不用加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文件夾里的文件名
打印結(jié)果
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"
)
????????兩個(gè)方法都可以,隱藏的文件也打印出來(lái)了简卧。
3.4 fileManager使用操作當(dāng)前目錄
//創(chuàng)建文件管理器
NSFileManager *fileManager =[NSFileManager defaultManager];
NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *documentsDirectory =[paths objectAtIndex:0];
//更改到待操作的目錄下
[fileManagerchangeCurrentDirectoryPath:[documentsDirectory stringByExpandingTildeInPath]];
//創(chuàng)建文件fileName文件名稱(chēng)连躏,contents文件的內(nèi)容,如果開(kāi)始沒(méi)有內(nèi)容可以設(shè)置為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];
????????這樣就創(chuàng)建了testFileNSFileManager.txt并把三個(gè)hello world寫(xiě)入文件了
????????changeCurrentDirectoryPath目錄更改到當(dāng)前操作目錄時(shí)拍棕,做文件讀寫(xiě)就很方便了,不用加上全路徑
3.5 刪除文件
????????接上面的代碼勺良,remove就ok了绰播。
[fileManager? removeItemAtPath:fileName error:nil];
3.6 混合數(shù)據(jù)的讀寫(xiě)
????????用NSMutableData創(chuàng)建混合數(shù)據(jù),然后寫(xiě)到文件里尚困。并按數(shù)據(jù)的類(lèi)型把數(shù)據(jù)讀出來(lái)
3.6.1 寫(xiě)入數(shù)據(jù)
NSString * fileName =@"testFileNSFileManager.txt";
NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *documentsDirectory = [pathsobjectAtIndex:0];
//獲取文件路徑
NSString *path = [documentsDirectorystringByAppendingPathComponent:fileName];
//待寫(xiě)入的數(shù)據(jù)
NSString *temp = @"nihao 世界";
int dataInt = 1234;
float dataFloat = 3.14f;
//創(chuàng)建數(shù)據(jù)緩沖
NSMutableData *writer = [[NSMutableDataalloc] init];
//將字符串添加到緩沖中
[writer appendData: [temp dataUsingEncoding: NSUTF8StringEncoding]];
//將其他數(shù)據(jù)添加到緩沖中
[writer appendBytes: &dataInt length: sizeof(dataInt)];
[writer appendBytes:&dataFloat length: sizeof(dataFloat)];
//將緩沖的數(shù)據(jù)寫(xiě)入到文件中
[writer writeToFile: path atomically:YES];
我們看看數(shù)據(jù)怎么樣了:
????????我們看到后面的是亂碼蠢箩,那是中文被轉(zhuǎn)成了NSData后,還有int float的二進(jìn)制
3.6.2 讀取剛才寫(xiě)入的數(shù)據(jù)
//讀取數(shù)據(jù):
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);
????????打印出來(lái)的結(jié)果:
2012-06-17? 23:51:14.723 IosSandbox[1285:f803] stringData:nihao hello! intData:1234332? floatData:3.140000
????????這里把寫(xiě)入的漢字改成了hello事甜。因?yàn)閇temp length]算長(zhǎng)度是谬泌,把中文算成一位了,出來(lái)的結(jié)果有誤逻谦。
4. 參考鏈接
iOS學(xué)習(xí)7:iOS沙盒(sandBox)機(jī)制(一)之獲取沙盒路徑及目錄說(shuō)明
http://my.oschina.net/joanfen/blog/151145
iOS學(xué)習(xí)之iOS沙盒(sandbox)機(jī)制和文件操作(一)
http://blog.csdn.net/totogo2010/article/details/7669837
iOS學(xué)習(xí)之iOS沙盒(sandbox)機(jī)制和文件操作(二)
http://blog.csdn.net/totogo2010/article/details/7670417
iOS學(xué)習(xí)之iOS沙盒(sandbox)機(jī)制和文件操作之NSFileManager(三)