《Objective-C 編程》26.沙盒&讀寫文件系統(tǒng)

每個(gè) iOS 應(yīng)用都有自己專屬的應(yīng)用沙盒(sandbox)披泪。應(yīng)用沙盒就是文件系統(tǒng)中的目錄恃慧,但是 iOS 系統(tǒng)會將每個(gè)應(yīng)用的沙盒目錄與文件系統(tǒng)的其他部分隔離部服。應(yīng)用只能訪問各自的沙盒哟忍。

應(yīng)用沙盒目錄

  • 應(yīng)用程序包(application bundle)
    包含應(yīng)用可執(zhí)行文件和所有資源文件,例如 NIB 文件和圖像文件瑟押。它是只讀目錄搀捷。

  • Doucments/ 目錄
    存放應(yīng)用運(yùn)行時(shí)生成的并且需要保留的數(shù)據(jù)。iTune 或 iCloud 會在同步設(shè)備時(shí)備份該目錄多望。當(dāng)設(shè)備發(fā)生故障時(shí)嫩舟,可以從 iTunes 或 iCloud 恢復(fù)該目錄中的文件。

  • Library/Caches/ 目錄

    存放應(yīng)用運(yùn)行時(shí)生成的需要保留的數(shù)據(jù)怀偷。與Documents/ 目錄不同的是家厌,iTunes 或 iCloud 不會在同步設(shè)備時(shí)備份該目錄。不備份緩存數(shù)據(jù)的主要原因是相關(guān)數(shù)據(jù)的體積可能會很大椎工,從而延長同步設(shè)備所需的時(shí)間饭于。如果數(shù)據(jù)源是在別處(例如web服務(wù)器)蜀踏,就可以將得到的數(shù)據(jù)保存在 Library/Caches/ 目錄。當(dāng)用戶需要恢復(fù)設(shè)備時(shí)掰吕,相關(guān)的應(yīng)用只需要從數(shù)據(jù)源(例如web服務(wù)器)再次獲取數(shù)據(jù)即可果覆。

  • Library/Preferences/ 目錄
    存放所有的偏好設(shè)置,iOS的設(shè)置(Setting)應(yīng)用也會在該目錄中查找應(yīng)用的設(shè)置信息殖熟。使用 NSUserDefaults 類随静,可以通過 Library/Preferences/ 目錄中的某個(gè)特定文件以鍵值對形式保存數(shù)據(jù)。iTunes或iCloud會在同步設(shè)備時(shí)備份該目錄吗讶。

  • tmp/ 目錄
    存放應(yīng)用運(yùn)行時(shí)所需的臨時(shí)數(shù)據(jù)。當(dāng)某個(gè)應(yīng)用沒有運(yùn)行時(shí)恋捆,iOS系統(tǒng)可能會清除該應(yīng)用的 tmp/ 目錄下的文件照皆,但是為了節(jié)約用戶設(shè)備空間,不能依賴這種自動清除機(jī)制沸停,而是當(dāng)應(yīng)用不再需要使用 tmp/ 目錄中的文件時(shí)膜毁,就及時(shí)手動刪除這寫文件。iTune或iCloud不會在同步設(shè)備時(shí)備份 tmp/ 目錄愤钾。通過 NSTemporaryDirectory 函數(shù)可以得到應(yīng)用沙盒中的 tmp/ 目錄的全路徑瘟滨。

獲取應(yīng)用文件夾目錄

文檔目錄:Doucments

// 返回應(yīng)用的 Documents 目錄:NSDocumentDirectory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// 獲取數(shù)組的第一個(gè)對象,是沙箱目錄中的【文檔文件夾】路徑能颁。在應(yīng)用中杂瘸,用戶的數(shù)據(jù)可以放在這里。在備份和恢復(fù)設(shè)備的時(shí)候伙菊,會包括此目錄败玉。
NSString *documentsDirectory = [paths firstObject];

NSLog(@"path: %@",documentsDirectory);
// path: /var/mobile/Containers/Data/Application/D0192F27-7976-4053-B694-8180D157E0FF/Documents

Library 目錄

// 返回應(yīng)用的 Library 目錄:NSLibraryDirectory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libraryDirectory = [paths firstObject];

Library/Caches 目錄

//獲取Library/Caches目錄路徑
NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]; 

Home 目錄

// 獲得程序的【Home文件夾】目錄
NSString *homeDirectory = NSHomeDirectory();
NSLog(@"Home Directory:%@",homeDirectory);

文件路徑的追加

NSString *homeDir = NSHomeDirectory(); 

NSString *documents = [homeDir stringByAppendingString:@"/Documents"];   
NSString *documents = [homeDir stringByAppendingPathComponent:@"Documents"]; //注意:不需要加‘/’

臨時(shí)目錄:tmp

// 獲得程序的【臨時(shí)文件夾】路徑,主要存放臨時(shí)文件镜硕。在設(shè)備的備份和恢復(fù)時(shí)运翼,不會備份此目錄。而且此目錄下的文件兴枯,可能會在應(yīng)用退出后被刪除血淌。
NSString *temporaryDirectory = NSTemporaryDirectory();
NSLog(@"temporary Directory:%@",temporaryDirectory);

資源文件目錄

// 獲得程序的【資源文件夾】路徑。
NSString *resourceDirectory = [[NSBundle mainBundle] resourcePath];

NSLog(@"resource Directory:%@",resourceDirectory);
// resource Directory:/var/containers/Bundle/Application/08772427-3ED4-40C0-95D7-D00B0D316A9E/Demo.app

第三方框架便捷語法:YYKit

獲取文檔沙盒目錄也可以使用 YYKit 框架中封裝好的便捷語法财剖,在 UIApplication+YYAdd類中定義成了相關(guān)的屬性供使用:

/// "Documents" folder in this app's sandbox.
@property (nonatomic, readonly) NSURL *documentsURL;
@property (nonatomic, readonly) NSString *documentsPath;

/// "Caches" folder in this app's sandbox.
@property (nonatomic, readonly) NSURL *cachesURL;
@property (nonatomic, readonly) NSString *cachesPath;

/// "Library" folder in this app's sandbox.
@property (nonatomic, readonly) NSURL *libraryURL;
@property (nonatomic, readonly) NSString *libraryPath;

// 內(nèi)部實(shí)現(xiàn)方法
// documents
- (NSURL *)documentsURL {
    return [[[NSFileManager defaultManager]
             URLsForDirectory:NSDocumentDirectory
             inDomains:NSUserDomainMask] lastObject];
}

- (NSString *)documentsPath {
    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
}

// caches
- (NSURL *)cachesURL {
    return [[[NSFileManager defaultManager]
             URLsForDirectory:NSCachesDirectory
             inDomains:NSUserDomainMask] lastObject];
}

- (NSString *)cachesPath {
    return [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
}

// library
- (NSURL *)libraryURL {
    return [[[NSFileManager defaultManager]
             URLsForDirectory:NSLibraryDirectory
             inDomains:NSUserDomainMask] lastObject];
}

- (NSString *)libraryPath {
    return [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject];
}

Xcode7 模擬器應(yīng)用沙盒查看

下面的方法可以查看【模擬器中的應(yīng)用沙盒】在Mac中的位置:

參考: Mac10.11 Xcode7 模擬器應(yīng)用沙盒查看(手動)

  1. 先查看模擬器 Identifier.
    Xcode ——Windows——Devices (或者快捷鍵 shift + cmd + 2)悠夯,記住Identifier所對應(yīng)的值。


  2. 打開Finder峰伙,shift + cmd + G 搜索路徑
    路徑:/Users/用戶名/Library/Developer/CoreSimulator/Devices/查找到的模擬器的Identitfier值/data/Containers/Data/Application/BAB08A8E-914C-4552-B58E-3015436D3F0E(項(xiàng)目的id)/Library/Caches

Tips:如何查看隱藏文件夾疗疟?使用快捷鍵:cmd+shift+,

  1. po NSHomeDirectory() 指令方法:
    在項(xiàng)目中的某處打一個(gè)斷點(diǎn),然后運(yùn)行程序瞳氓,在控制臺窗口All Output中(lldb)后面輸入"po NSHomeDirectory()"
    參考:如何快速定位應(yīng)用的沙盒存放路徑

模擬器在Mac中的位置:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/

讀寫文件

NSString

將 NSString 對象寫入文件

NSMutableString *str = [[NSMutableString alloc] init];
for (int i = 0; i < 10; i++) {
    [str appendString:@"Aaron is cool! \n"];
}

// 聲明一個(gè)指向 NSError 對象的指針策彤,但是不創(chuàng)建相應(yīng)的對象
// 實(shí)際上栓袖,只有當(dāng)發(fā)生錯誤時(shí),才會由 writeToFile 創(chuàng)建相應(yīng)的 NSError 對象
NSError *error;

// 將 NSError 指針通過引用傳入 writeToFile:atomically:encoding:error: 方法
BOOL success = [str writeToFile:@"/tmp/cool.txt"
                     atomically:YES
                       encoding:NSUTF8StringEncoding
                          error:&error];

// 檢查返回的布爾值店诗,如果寫入文件夾失敗裹刮,就查詢 NSError 對象并輸出錯誤描述
if (success) {
     NSLog(@"done writing /tmp/cool.txt");
}else {
    NSLog(@"writing /tmp/cool.txt failed:%@",[error localizedDescription]);
}

通過 NSString 讀取文件

NSError *readError;
NSString *readStr = [[NSString alloc]
                     initWithContentsOfFile:@"/etc/resolve.conf"
                                   encoding:NSASCIIStringEncoding
                                      error:&readError];

if (!readStr) {
    NSLog(@"read failed:%@",[error localizedDescription]);
}else {
    NSLog(@"resolve.conf looks like this: %@",readStr);
}

文件路徑的追加

// 獲取沙盒Home路徑
NSString *homeDir = NSHomeDirectory(); 
NSString *documents = [homeDir stringByAppendingString:@"/Documents"];   
NSString *documents = [homeDir stringByAppendingPathComponent:@"Documents"]; //注意:不需要加‘/’

NSString 處理路徑

//演示路徑 
NSString *path = @"/Users/apple/file.text";

// 1.獲取路徑的組成部分  結(jié)果: (“/”,”Users”, “apple”, “file.text”) 
NSArray *components = [path pathComponents];

// 2.路徑的最后一個(gè)組成部分   結(jié)果: file.text
NSString *lastName = [path lastPathComponent];

// 3.追加文件或目錄  結(jié)果: /Users/apple/file.text/app.text
NSString *filePath = [path stringByAppendingPathComponent:@"app.text"];

// 4.刪除最后部分的組成部分 結(jié)果: /Users/apple
NSString *filePath = [path stringByDeletingLastPathComponent];

// 5. 取路徑最后部分的擴(kuò)展名 結(jié)果: text
NSString *extName = [path pathExtension];

// 6. 追加擴(kuò)展名   結(jié)果: /Users/apple/file.text.jpg
NSString *filePath = [path stringByAppendingPathExtension:@"jpg"];

文件路徑
簡單來說就是我們不應(yīng)該使用 NSString 來描述文件路徑庞瘸。對于 OS X 10.7 和 iOS 5捧弃,NSURL 更便于使用,而且更有效率擦囊,它還能緩存文件系統(tǒng)的屬性违霞。

再者,NSURL 有八個(gè)方法來訪問被稱為 resource values 的東西瞬场。這些方法提供了一個(gè)穩(wěn)定的接口买鸽,使我們可以用來獲取和設(shè)置文件與目錄的各種屬性,例如本地化文件名(NSURLLocalizedNameKey)贯被、文件大醒畚濉(NSURLFileSizeKey),以及創(chuàng)建日期(NSURLCreationDateKey)彤灶,等等看幼。

尤其是在遍歷目錄內(nèi)容時(shí),使用 -[NSFileManager enumeratorAtURL:includingPropertiesForKeys:options:errorHandler:]幌陕,并傳入一個(gè)關(guān)鍵詞(keys)列表诵姜,然后用 -getResourceValue:forKey:error: 檢索它們,能帶來顯著的性能提升苞轿。

下面是一個(gè)簡短的例子展示了如何將它們組合在一起:

NSError *error = nil;
NSFileManager *fm = [[NSFileManager alloc] init];

// documentsURL
NSURL *documents = [fm URLForDirectory:NSDocumentationDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:&error];

// 構(gòu)造枚舉器
NSArray *properties = @[NSURLLocalizedNameKey, NSURLCreationDateKey];
NSDirectoryEnumerator *dirEnumerator = [fm enumeratorAtURL:documents
                                includingPropertiesForKeys:properties
                                                   options:0
                                              errorHandler:nil];

// 遍歷 documents 文件目錄
for (NSURL *fileURL in dirEnumerator) {
    NSString *name = nil;
    NSDate *creationDate = nil;
    if ([fileURL getResourceValue:&name forKey:NSURLLocalizedNameKey error:NULL] &&
        [fileURL getResourceValue:&creationDate forKey:NSURLCreationDateKey error:NULL])
    {
        NSLog(@"'%@' was created at %@", name, creationDate);
    }
}

我們把屬性的鍵傳給 -enumeratorAtURL:...方法中茅诱,在遍歷目錄內(nèi)容時(shí),這個(gè)方法能確保用非常高效的方式獲取它們搬卒。在循環(huán)中瑟俭,調(diào)用 -getResourceValue:... 能簡單地從 NSURL 得到已緩存的值,而不用去訪問文件系統(tǒng)契邀。

路徑類型轉(zhuǎn)換

// 創(chuàng)建文件管理器
NSFileManager *fileManager = [NSFileManager defaultManager];

// 1. 創(chuàng)建 NSURL 類型的 documents 路徑
NSURL *documentsURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject];
    
// 1.1 NSURL ——> NSString
NSString *documentsPath = documentsURL.path;
    
// 1.2 NSURL ——> File Reference URL
NSURL *fileReferenceURL = documentsURL.fileReferenceURL;

// 2. 創(chuàng)建 NSString 類型的 documents 路徑
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;

// 2.1 NSString ——> NSURL
NSURL *documentsURL = [NSURL fileURLWithPath:documentsPath];

NSData

  • NSData 對象“代表”內(nèi)存中的某塊緩沖區(qū)摆寄,可以保存相應(yīng)字節(jié)數(shù)的數(shù)據(jù)。
  • NSData 是對數(shù)據(jù)的一種抽象坯门。
  • 任何數(shù)據(jù)都可以通過 NSData 來存儲微饥,NSMutableData 是可變的,繼承于 NSData古戴。

將 NSData 對象下載的數(shù)據(jù)寫入文件

NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
NSString *str = @"https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/logo_white_fe6da1ec.png";
NSURL *url = [NSURL URLWithString:str];
NSURLSessionDataTask *task = [[NSURLSession sharedSession]
                              dataTaskWithURL:url
                              completionHandler:
  ^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

    if (!data) {
        NSLog(@"fetch failed: %@",[error localizedDescription]);
    }
    NSLog(@"The file is %lu bytes",(unsigned long)[data length]);

    NSError *writtenError = nil;
    // NSData 對象會先將數(shù)據(jù)寫入臨時(shí)文件欠橘,成功后再移動至指定的路徑
    BOOL written = [data writeToFile:@"/tmp/baidu.png"
                             options:NSDataWritingAtomic
                               error:&writtenError];
    if (!written) {
        NSLog(@"written failed: %@",[writtenError localizedDescription]);
    }
    NSLog(@"written success");

}];

//  NSURLSessionDataTask 在剛創(chuàng)建的時(shí)候處于暫停狀態(tài),需要手動調(diào)用resume方法恢復(fù),讓NSURLSessionDataTask 開始向服務(wù)器發(fā)送請求现恼。
[task resume];
[runLoop run];

從文件讀取數(shù)據(jù)并存入 NSData 對象

NSData *readData = [NSData dataWithContentsOfFile:@"tmp/baidu.png" options:NSDataReadingMappedIfSafe error:nil];
NSLog(@"The file read from the disk has %lu bytes",(unsigned long)[readData length]);

尋找特別目錄

// 方法會返回包含指定的數(shù)組
NSArray *desktops = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES);
// 我知道用戶只有一個(gè)桌面文件夾
NSString *desktopPath = desktops[0];
NSLog(@"desktop Path:%@",desktopPath);

目錄枚舉:

typedef NS_ENUM(NSUInteger, NSSearchPathDirectory) {
    NSApplicationDirectory = 1,             // supported applications (Applications)
    NSDemoApplicationDirectory,             // unsupported applications, demonstration versions (Demos)
    NSDeveloperApplicationDirectory,        // developer applications (Developer/Applications). DEPRECATED - there is no one single Developer directory.
    NSAdminApplicationDirectory,            // system and network administration applications (Administration)
    NSLibraryDirectory,                     // various documentation, support, and configuration files, resources (Library)
    NSDeveloperDirectory,                   // developer resources (Developer) DEPRECATED - there is no one single Developer directory.
    NSUserDirectory,                        // user home directories (Users)
    NSDocumentationDirectory,               // documentation (Documentation)
    NSDocumentDirectory,                    // documents (Documents)
    NSCoreServiceDirectory,                 // location of CoreServices directory (System/Library/CoreServices)
    NSAutosavedInformationDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 11,   // location of autosaved documents (Documents/Autosaved)
    NSDesktopDirectory = 12,                // location of user's desktop
    NSCachesDirectory = 13,                 // location of discardable cache files (Library/Caches)
    NSApplicationSupportDirectory = 14,     // location of application support files (plug-ins, etc) (Library/Application Support)
    NSDownloadsDirectory NS_ENUM_AVAILABLE(10_5, 2_0) = 15,              // location of the user's "Downloads" directory
    NSInputMethodsDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 16,           // input methods (Library/Input Methods)
    NSMoviesDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 17,                 // location of user's Movies directory (~/Movies)
    NSMusicDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 18,                  // location of user's Music directory (~/Music)
    NSPicturesDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 19,               // location of user's Pictures directory (~/Pictures)
    NSPrinterDescriptionDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 20,     // location of system's PPDs directory (Library/Printers/PPDs)
    NSSharedPublicDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 21,           // location of user's Public sharing directory (~/Public)
    NSPreferencePanesDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 22,        // location of the PreferencePanes directory for use with System Preferences (Library/PreferencePanes)
    NSApplicationScriptsDirectory NS_ENUM_AVAILABLE(10_8, NA) = 23,      // location of the user scripts folder for the calling application (~/Library/Application Scripts/code-signing-id)
    NSItemReplacementDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 99,       // For use with NSFileManager's URLForDirectory:inDomain:appropriateForURL:create:error:
    NSAllApplicationsDirectory = 100,       // all directories where applications can occur
    NSAllLibrariesDirectory = 101,          // all directories where resources can occur
    NSTrashDirectory NS_ENUM_AVAILABLE(10_8, NA) = 102                   // location of Trash directory

};

NSString <—> NSData

NSString *string1 = @"NSData是對數(shù)據(jù)的一種抽象";
// NSString -> NSData
NSData *data = [string1 dataUsingEncoding:NSUTF8StringEncoding];

// NSData -> NSString
NSString *string2 =[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

NSFileManager

NSFileManager 主要對文件進(jìn)行管理肃续,主要有如下功能:創(chuàng)建黍檩、復(fù)制、刪除始锚、剪切等刽酱。常見的 NSFileManager 文件方法:

方法 描述
- (NSData *)contentsAtPath: 從一個(gè)文件中讀取數(shù)據(jù)
- (BOOL)createFileAtPath: contents: attributes: 向一個(gè)文件寫入數(shù)據(jù)
- (BOOL)copyItemAtPath: toPath: error: 復(fù)制文件
- (BOOL)moveItemAtPath: toPath: error: 重命名或移動一個(gè)文件
- (BOOL)linkItemAtPath: toPath: error: 在指定的路徑上創(chuàng)建項(xiàng)目之間的硬連接
- (BOOL)removeItemAtPath: error: 刪除文件
- (BOOL)contentsEqualAtPath: andPath: 比較這兩個(gè)文件的內(nèi)容
- (BOOL)fileExistsAtPath: 測試文件是否存在
- (BOOL)isReadableFileAtPath: 測試文件是否存在,并且是否能執(zhí)行讀操作
- (BOOL)isWritableFileAtPath: 測試文件是否存在瞧捌,并且是否能執(zhí)行寫操作
- (NSDictionary *)attributesOfItemAtPath: error: 獲取文件的屬性
- (BOOL)setAttributes:(NSDictionary *)attributes ofItemAtPath: error 更改文件的屬性

創(chuàng)建文件

//創(chuàng)建 NSFileManager 對象
NSFileManager *fileManager = [[NSFileManager alloc] init];    
NSFileManager *fileManager = [NSFileManager defaultManager];  //同上
        
//1.構(gòu)造文件的路徑
NSString *homePath = NSHomeDirectory();
NSString *filePath = [homePath stringByAppendingPathComponent:@"file.txt"];

//2.構(gòu)造數(shù)據(jù)
NSString *string = @"Hello World!";
    
//3.將字符串中的文本數(shù)據(jù)存儲到Data對象中
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];

//4.創(chuàng)建文件
//createFileAtPath 創(chuàng)建文件棵里,如果文件已經(jīng)存在,那么新創(chuàng)建的文件會將原文件覆蓋
BOOL success = [fileManager createFileAtPath:filePath //路徑
                                        contents:data //數(shù)據(jù)
                                      attributes:nil]; //屬性
if (success) {
        NSLog(@"create file success");
    }

創(chuàng)建并返回文件夾列表

// 創(chuàng)建并返回文件夾路徑:../Library/Private Documents/
+ (NSString *)getPrivateDocsDir {
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    
    documentsDirectory = [documentsDirectory stringByAppendingPathComponent:@"Private Documents"];

    NSError *error;
    [[NSFileManager defaultManager] createDirectoryAtPath:documentsDirectory withIntermediateDirectories:YES attributes:nil error:&error];
    
    return documentsDirectory;
}

// 返回?cái)?shù)組:存放的是 Scary bug 文件夾名稱列表:../Library/Private Documents/#.scarybug
+ (NSMutableArray *)loadScaryBugDocs {
    
    // Get private docs dir
    NSString *documentsDirectiory = [HQLScaryBugDatabase getPrivateDocsDir];
    NSLog(@"Loading bugs from %@",documentsDirectiory);
    
    // Get contents of documents directiory 獲取文檔目錄列表
    NSError *error;
    NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectiory error:&error];
    if (!files) {
        NSLog(@"Error reading contents of documents directory:%@",error.localizedDescription);
        return nil;
    }
    
    // Create HQLScaryBugDoc for each file
    // Documents/Private Documents/#.scarybug
    NSMutableArray *retval = [NSMutableArray arrayWithCapacity:files.count];
    for (NSString *file in files) {
        // 判斷文件擴(kuò)展名是否相同
        if ([file.pathExtension compare:@"scarybug" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
            NSString *fullPath = [documentsDirectiory stringByAppendingPathComponent:file];
            HQLScaryBugDoc *doc = [[HQLScaryBugDoc alloc] initWithDocPath:fullPath];
            [retval addObject:doc];
        }
    }
    return retval;
}

創(chuàng)建文件夾

[fileManager createDirectoryAtPath:(NSString *) withIntermediateDirectories:(BOOL) attributes:(NSDictionary *) error:(NSError *__autoreleasing *)] 

讀取文件

//創(chuàng)建 NSFileManager 對象
NSFileManager *fileManager = [NSFileManager defaultManager]; 

//構(gòu)造文件的路徑
NSString *homePath = NSHomeDirectory();
NSString *filePath = [homePath stringByAppendingPathComponent:@"file.txt"];

//根據(jù)路徑讀取文件
NSData *fileData = [fileManager contentsAtPath:filePath];

//將NSData轉(zhuǎn)NSString
NSString *content = [[NSString alloc] initWithData:fileData
                             encoding:NSUTF8StringEncoding];

移動姐呐,剪切文件

NSFileManager *fileManager = [NSFileManager defaultManager];

//構(gòu)造路徑
//文件的原路徑
NSString *srcPath = [NSHomeDirectory() stringByAppendingPathComponent:@"file.txt"];     
//文件剪切之后的路徑
NSString *toPath = [NSHomeDirectory() stringByAppendingPathComponent:@"temp/file.txt"];
    
//注意:如果目標(biāo)路徑已經(jīng)存在此文件殿怜,那么會導(dǎo)致操作失敗
NSError *error = nil;
BOOL success = [fileManager moveItemAtPath:srcPath
                                        toPath:toPath
                                         error:&error];
if (!success) {
    NSLog(@"剪切失敗,%@",error);
    }

復(fù)制文件

NSFileManager *fileManager = [NSFileManager defaultManager];

//1.構(gòu)造路徑
//文件的原路徑
NSString *srcPath = [NSHomeDirectory() stringByAppendingPathComponent:@"temp/file.txt"];    
//文件復(fù)制之后的路徑
NSString *toPath = [NSHomeDirectory() stringByAppendingPathComponent:@"file.txt"];
    
BOOL success = [fileManager copyItemAtPath:srcPath
                                        toPath:toPath
                                         error:nil];
//注意:如果目標(biāo)路徑已經(jīng)存在此文件,那么會導(dǎo)致操作失敗
if (!success) {
        NSLog(@"復(fù)制失敗");
    }

刪除文件

NSFileManager *fileManager = [NSFileManager defaultManager];

//1.構(gòu)造文件路徑
NSString *toPath = [NSHomeDirectory() stringByAppendingPathComponent:@"file.txt"];
    
//2.判斷文件是否存在
BOOL exist = [fileManager fileExistsAtPath:toPath];
if (exist) {
//3.刪除文件
    if ([fileManager removeItemAtPath:toPath error:nil]) {
            NSLog(@"刪除文件成功");
        }
    }

刪除文件夾

刪除文件或文件夾之前曙砂,務(wù)必判斷文件是否存在稳捆,否則會造成過度釋放。

NSString *dir = [NSHomeDirectory() stringByAppendingPathComponent:@"temp"];
[fileManager removeItemAtPath:dir error:nil];

文件屬性

NSFileManager *fileManager = [NSFileManager defaultManager];

//1.構(gòu)造文件路徑    
NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"file.txt"];

//獲得文件的屬性字典     
NSDictionary *fileAttribute = [fileManager attributesOfItemAtPath:filePath error:nil];
NSLog(@"%@",fileAttribute);

//獲取文件大小    
NSNumber *fileSize = [fileAttribute objectForKey:@"NSFileSize"];
long size = [fileSize longValue];
NSLog(@"size = %ld",size);

獲取文件夾中所有的文件

NSFileManager *fileManager = [NSFileManager defaultManager];

//1.構(gòu)造路徑
NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"壁紙"];
    
//2.獲取文件夾中所有的子文件路徑(路徑是相對路徑)
NSArray *subPaths = [fileManager subpathsOfDirectoryAtPath:filePath error:nil];
    
//3.遍歷每一個(gè)子路徑
long sum = 0;
for (NSString *subpath in subPaths) {
        
//4.子路徑與父路徑拼接
NSString *path = [filePath stringByAppendingPathComponent:subpath];
        
//5.獲取文件的屬性麦轰,計(jì)算所有文件占用內(nèi)存大小
NSDictionary *fileAttribute = [fileManager attributesOfItemAtPath:path error:nil];
        
NSNumber *filesize = fileAttribute[@"NSFileSize"];
long size = [filesize longValue];
sum += size;
}
//6.單位換算
float result = sum / (1000*1000.0);
NSLog(@"result = %.1f",result);

NSArray

寫文件

  • 數(shù)組、字典砖织、字符串款侵、NSData都是容納數(shù)據(jù)的,他們都有一個(gè)writeToFile方法, 將數(shù)據(jù)寫入文件。
  • 數(shù)組侧纯、字典寫入的文件叫屬性列表 (plist) 文件,可以用Xcode打開編輯新锈。
  • 數(shù)組只能將如下數(shù)據(jù)類型寫入文件,如果包含其他對象,將寫入失敗。NSNumber眶熬、NSString妹笆、NSData、NSDate娜氏、NSArray拳缠、NSDictionary
// 需要保存的數(shù)組
NSArray *array = @[@"1", @"2", @"3", @"4", @"5",];

// 構(gòu)建路徑
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *document = [pathArray lastObject];
NSString *documentPath = [document stringByAppendingPathComponent:@"city.plist"];

// 判斷文件夾是否存在
if (![[NSFileManager defaultManager] fileExistsAtPath:document]) {
    [[NSFileManager defaultManager] createDirectoryAtPath:documentPath withIntermediateDirectories:YES attributes:nil error:nil];
}
NSLog(@"path:%@",documentPath);

// 將數(shù)組保存到 Documents 目錄下,文件名為 city.plist
BOOL isSucceed = [array writeToFile:documentPath atomically:YES];
NSLog(@"isSucceed = %@",isSucceed ? @"YES" : @"NO");

讀文件

//數(shù)組讀文件
//1.通過alloc創(chuàng)建贸弥,并讀入文件數(shù)據(jù)
NSArray *alloc = [[NSArray alloc] initWithContentsOfFile:path]; 
    
//2.通過類方法創(chuàng)建窟坐,并讀入文件數(shù)據(jù)
MSArray *array = [NSArray arrayWithContentsofFile:path];

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市绵疲,隨后出現(xiàn)的幾起案子哲鸳,更是在濱河造成了極大的恐慌,老刑警劉巖盔憨,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件徙菠,死亡現(xiàn)場離奇詭異,居然都是意外死亡郁岩,警方通過查閱死者的電腦和手機(jī)婿奔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門缺狠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人脸秽,你說我怎么就攤上這事儒老。” “怎么了记餐?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵驮樊,是天一觀的道長。 經(jīng)常有香客問我片酝,道長囚衔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任雕沿,我火速辦了婚禮练湿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘审轮。我一直安慰自己肥哎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布疾渣。 她就那樣靜靜地躺著篡诽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪榴捡。 梳的紋絲不亂的頭發(fā)上杈女,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音吊圾,去河邊找鬼达椰。 笑死,一個(gè)胖子當(dāng)著我的面吹牛项乒,可吹牛的內(nèi)容都是我干的啰劲。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼檀何,長吁一口氣:“原來是場噩夢啊……” “哼呈枉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起埃碱,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤猖辫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后砚殿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啃憎,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年似炎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辛萍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悯姊。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖贩毕,靈堂內(nèi)的尸體忽然破棺而出悯许,到底是詐尸還是另有隱情,我是刑警寧澤辉阶,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布先壕,位于F島的核電站,受9級特大地震影響谆甜,放射性物質(zhì)發(fā)生泄漏垃僚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一规辱、第九天 我趴在偏房一處隱蔽的房頂上張望谆棺。 院中可真熱鬧,春花似錦罕袋、人聲如沸改淑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽溅固。三九已至,卻和暖如春兰珍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背询吴。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工掠河, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人猛计。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓唠摹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親奉瘤。 傳聞我的和親對象是個(gè)殘疾皇子勾拉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容