基礎篇- 沙盒以及檔案的操作和存取

weixin_34138377發表於2017-12-12
1755386-5b68dcc397f8385a.jpg

來感受下iOS app的沙盒

1755386-9ddcd0015129efdd.png
官方文件圖片,自行感受下

沙盒機制(sandBox)

iOS應用程式只能在為該改程式建立的檔案系統中讀取檔案,不可以去其它地方訪問,此區域被稱為沙盒,所有的非程式碼檔案都要儲存在此,例如影像,圖示,聲音,映像,屬性列表,文字檔案等。

  • 每個應用程式都有自己的儲存空間。
  • 應用程式不能翻過自己的圍牆去訪問別的儲存空間的內容。
  • 應用程式請求的資料都要通過許可權檢測,假如不符合條件的話,不會被放行。

如果要訪問到其他 App 的範圍,必須要獲取管理員許可才行,比如地理位置,相簿,通訊錄,話筒等。這是蘋果系統的哲學,蘋果認為只有把各個 App 孤立起來才能營造良好的使用者體驗和安全性。

通過下面的圖來看一下蘋果的沙盒機制吧.

1755386-8957bffb079a376b.png

通過這張圖只能從表層上理解sandbox是一種安全體系,應用程式的所有操作都要通過這個體系來執行,其中核心內容是:sandbox對應用程式執行各種操作的許可權限制。

沙盒目錄結構

預設情況下,每個沙盒含有3個資料夾:Documents, Library 和 Tmp。因為應用的沙盒機制,應用只能在幾個目錄下讀寫檔案

Documents:蘋果建議將程式中建立的或在程式中瀏覽到的檔案資料儲存在該目錄下,iTunes備份和恢復的時候會包括此目錄。

Library:蘋果建議用來存放預設設定或其它狀態資訊。會被iTunes同步但是要除了Caches子目錄外。

  • Library/Caches:主要是快取檔案,使用者使用過程中快取都可以儲存在這 個目錄中。這個目錄就用於儲存那些可再生的檔案,可以重新下載或者重新生成的資料應該儲存在目錄下面。(比如雜誌、新聞、地圖應用使用的資料庫快取檔案和可下載內容應該儲存到這個資料夾)。磁碟空間不夠時 系統會刪除 不會被iTunes同步。

  • Library/Preferences:應用程式的偏好設定檔案。我們使用NSUserDefaults寫的設定資料都會儲存到該目錄下的一個plist檔案中,這就是所謂的寫道plist中! 會被iTunes同步。

tmp:各種臨時檔案,儲存應用再次啟動時不需要的檔案。而且,當應用不再需要這些檔案時應該主動將其刪除,因為該目錄下的東西隨時有可能被系統清理掉,也可能隨著專案退出刪掉。不會被iTunes同步。

iPhone在重啟時,會丟棄所有的tmp檔案。

沙盒檔案的操作

獲取程式的home目錄

  NSString *homeDirectory = NSHomeDirectory();
  NSLog(@"path:%@", homeDirectory);

獲取document目錄

  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  NSString *path = [paths objectAtIndex:0];
  NSLog(@"path:%@", path);

獲取Cache目錄

  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
  NSString *path = [paths objectAtIndex:0];
  NSLog(@"%@", path);

獲取Library目錄

  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
   NSString *path = [paths objectAtIndex:0];
  NSLog(@"%@", path);

獲取Tmp目錄

  NSString *tmpDir = NSTemporaryDirectory();
  NSLog(@"%@", tmpDir);

存資料到沙盒plist檔案中。

  +(void)writeDataToPlist :(NSMutableArray *)dataArray
  {
        NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
        NSString *path=[paths    objectAtIndex:0];
        NSLog(@"path:%@",path);
        NSString *filename=[path stringByAppendingPathComponent:@"searchHistory.plist"];
        //寫入
        NSFileManager* fm = [NSFileManager defaultManager];
        [fm createFileAtPath:filename contents:nil attributes:nil];
        [dataArray writeToFile:filename atomically:YES];
      }

沙盒plist檔案讀取

   +(NSArray *)getDataFormPlist{

        NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
        NSString *path=[paths objectAtIndex:0];
        NSString *filename=[path stringByAppendingPathComponent:@"searchHistory.plist"];
        //讀檔案
        NSArray* dataArray = [NSArray arrayWithContentsOfFile:filename];
        return dataArray;
  }

可以檢視沙盒的應用

1755386-52399e25bcac1a57.png
檢視真機應用沙盒子
1755386-7510dd2162784c19.png
檢視模擬器應用沙盒

檔案常見操作

判斷某檔案是否存在

  NSFileManager* fm=[NSFileManager defaultManager];
   if(![fm fileExistsAtPath:[self dataFilePath]]){
      //下面是對該檔案進行制定路徑的儲存
     [fm createDirectoryAtPath:[self dataFilePath] withIntermediateDirectories:YES attributes:nil error:nil];
  }

儲存某個檔案

可以用 NSFileManager的
  - (BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data attributes:(NSDictionary *)attr;
或 NSData 的
  - (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
  - (BOOL)writeToFile:(NSString *)path options:(NSUInteger)writeOptionsMask error:(NSError **)errorPtr;

刪除檔案

 NSFileManager* fm=[NSFileManager defaultManager];
 NSError *myError = nil;
if ([fm removeItemAtPath:@"" error:&myError] == YES){
}

移動檔案

NSFileManager* fm=[NSFileManager defaultManager];
 NSError *myError = nil;
if ([fm moveItemAtPath:@"" toPath:@"" error:&myError] == YES){
}

拷貝檔案

NSFileManager* fm=[NSFileManager defaultManager];
 NSError *myError = nil;
if ([fm copyItemAtPath:@"" toPath:@"" error:&myError] == YES){
    
}

取得一個目錄下得所有檔名

 NSArray *files = [fm subpathsAtPath: [self dataFilePath] ];

讀取某個檔案

  NSData *data = [fm contentsAtPath:[self dataFilePath]];
  //或者
  NSData *data = [NSData dataWithContentOfPath:[self dataFilePath]];

儲存漢字

NSString *fileName=[[paths objectAtIndex:0] stringByAppendingPathComponent:@"myFile.txt"];
NSString *content=@"更深夜靜人已息";
NSData *contentData=[content dataUsingEncoding:NSUnicodeStringEncoding];
  if ([contentData writeToFile:fileName atomically:YES]) {
    NSLog(@">>write ok.");
  }

使用工程中的檔案

  NSString *myFilePath = [[NSBundle mainBundle] pathForResource:@"f"   ofType:@"txt"];
  NSString *myFileContent=[NSString stringWithContentsOfFile:myFilePath encoding:NSUTF8StringEncoding error:nil];
 NSLog(@"bundel file path: %@ \nfile content:%@",myFilePath,myFileContent);

小結

後續如果有新的相關知識get,會持續更新。

相關文章