通常情况下,每个沙盒包含以下目录及文件:
目录结构如下图所示:
补充1:对于上述描述可以这样举例理解,一个记事本应用,用户写的东西需要保存起来,这些东西是用户自行生成的,则需要放在 Documents 目录里。一个新闻应用,如果需要从服务器下载东西展示给用户看,下载的东西就放在 Library/Caches 目录里。苹果审核对这个要求很严格,主要原因是 iCloud 的同步问题。
补充2:如果想知道真机或者模拟器 App 沙盒路径,可通过在项目中执行下述代码打印获取:
NSString *homeDirectoryPath = NSHomeDirectory();
// 获取沙盒根目录路径 NSString *homeDirectoryPath = NSHomeDirectory(); // 获取 Applications 路径 NSString *appDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSUserDomainMask, YES) objectAtIndex:0]; // 获取 Documents 路径 NSString *documentDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; // 获取 Caches 路径 NSString *cachesDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]; // 获取 tmp 路径 NSString *tmpDirectoryPath = NSTemporaryDirectory();
使用 FileManager 可以对沙盒中的目录、文件进行操作。通过如下方式可以获取 NSFileManager 的单例:
[NSFileManager defaultManager]
iOS 应用都是通过 bundle 进行封装的,可以狭隘地将 bundle 理解为上述沙盒中的 AppName.app 文件。在 Finder 中,会把 bundle 当做一个文件显示从而防止用户误操作导致程序文件损坏,但其实内部是一个目录,包含了图像、媒体资源、编译好的代码、nib 文件等,这个目录称为 main bundle。
Cocaoa 提供了 NSBundle 类封装了 bundle 操作。
// 获取应用程序的 main bundle NSBundle *mainBundle = NSBundle.mainBundle; // 使用 main bundle 获取资源路径 NSString *filePath = [mainBundle pathForResource:@"logo" ofType:@"png"];
#import <UIKit/UIKit.h> @interface FileUtil : NSObject /** * 获取 home 路径 * * @return */ + (NSString *)homeDirectoryPath; /** * 获取 app 路径 * * @return */ + (NSString *)appDirectoryPath; /** * 获取 document 路径 * * @return */ + (NSString *)documentDirectoryPath; /** * 获取 caches 路径 * * @return */ + (NSString *)cachesDirectoryPath; /** * 获取 tmp 路径 * * @return */ + (NSString *)tmpDirectoryPath; /** * 判断目录是否存在 * * @param directoryPath 目录路径 * * @return */ + (BOOL)directoryExist:(NSString *)directoryPath; /** * 判断文件是否存在 * * @param filePath 文件路径 * * @return */ + (BOOL)fileExist:(NSString *)filePath; /** * 在父目录下创建子目录 * * @param parentDirectoryPath 父目录路径 * @param directoryName 子目录名称 * * @return */ + (BOOL)createDirectoryAtParentDirectory:(NSString *)parentDirectoryPath directoryName:(NSString *)directoryName; /** * 在父目录下创建子文件 * * @param parentDirectoryPath 父目录路径 * @param fileName 子文件名称 * * @return */ + (BOOL)createFileAtParentDirectory:(NSString *)parentDirectoryPath fileName:(NSString *)fileName; /** * 删除目录 * * @param directoryPath 目录路径 * * @return */ + (BOOL)deleteDirectoryAtPath:(NSString *)directoryPath; /** * 删除文件 * * @param filePath 文件路径 * * @return */ + (BOOL)deleteFileAtPath:(NSString *)filePath; /** * 获取父目录下的子内容(包含目录和文件) * * @param parentDirectoryPath 父目录路径 * * @return */ + (NSArray *)contentsAtParentDirectory:(NSString *)parentDirectoryPath; /** * 获取父目录下的所有子目录名称 * * @param parentDirectoryPath 父目录路径 * * @return */ + (NSArray *)directoryNamesAtParentDirectory:(NSString *)parentDirectoryPath; /** * 获取父目录下的所有子目录路径 * * @param parentDirectoryPath 父目录路径 * * @return */ + (NSArray *)directoryPathsAtParentDirectory:(NSString *)parentDirectoryPath; /** * 获取父目录下的所有子文件名称 * * @param parentDirectoryPath 父目录路径 * * @return */ + (NSArray *)fileNamesAtParentDirectoryPath:(NSString *)parentDirectoryPath; /** * 获取父目录下的所有子文件路径 * * @param parentDirectoryPath 父目录路径 * * @return */ + (NSArray *)filePathsAtParentDirectoryPath:(NSString *)parentDirectoryPath; @endFileUtil.m
#import "FileUtil.h" @interface FileUtil () @end @implementation FileUtil + (NSString *)homeDirectoryPath { return NSHomeDirectory(); } + (NSString *)appDirectoryPath { NSArray *array = NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSUserDomainMask, YES); return [array objectAtIndex:0]; } + (NSString *)documentDirectoryPath { NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); return [array objectAtIndex:0]; } + (NSString *)cachesDirectoryPath { NSArray *array = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); return [array objectAtIndex:0]; } + (NSString *)tmpDirectoryPath { return NSTemporaryDirectory(); } + (BOOL)directoryExist:(NSString *)directoryPath { NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL isDirectory = NO; BOOL exist = [fileManager fileExistsAtPath:directoryPath isDirectory:&isDirectory]; if (isDirectory && exist) { return YES; } return NO; } + (BOOL)fileExist:(NSString *)filePath { NSFileManager *fileManager = [NSFileManager defaultManager]; return [fileManager fileExistsAtPath:filePath]; } + (BOOL)createDirectoryAtParentDirectory:(NSString *)parentDirectoryPath directoryName:(NSString *)directoryName { NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *directoryPath = [NSString stringWithFormat:@"%@/%@", parentDirectoryPath, directoryName]; return [fileManager createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:nil]; } + (BOOL)createFileAtParentDirectory:(NSString *)parentDirectoryPath fileName:(NSString *)fileName { NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *filePath = [NSString stringWithFormat:@"%@/%@", parentDirectoryPath, fileName]; return [fileManager createFileAtPath:filePath contents:nil attributes:nil]; } + (BOOL)deleteDirectoryAtPath:(NSString *)directoryPath { NSFileManager *fileManager = [NSFileManager defaultManager]; if ([self directoryExist:directoryPath]) { return [fileManager removeItemAtPath:directoryPath error:nil]; } return NO; } + (BOOL)deleteFileAtPath:(NSString *)filePath { NSFileManager *fileManager = [NSFileManager defaultManager]; if ([self fileExist:filePath]) { return [fileManager removeItemAtPath:filePath error:nil]; } return NO; } + (NSArray *)contentsAtParentDirectory:(NSString *)parentDirectoryPath { NSFileManager *fileManager = [NSFileManager defaultManager]; return [fileManager contentsOfDirectoryAtPath:parentDirectoryPath error:nil]; } + (NSArray *)directoryNamesAtParentDirectory:(NSString *)parentDirectoryPath { NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL isDirectory = NO; NSMutableArray *directoryPaths = [[NSMutableArray alloc] init]; for (NSString *content in [self contentsAtParentDirectory:parentDirectoryPath]) { NSString *path = [NSString stringWithFormat:@"%@/%@", parentDirectoryPath, content]; if ([fileManager fileExistsAtPath:path isDirectory:&isDirectory]) { if (isDirectory) { [directoryPaths addObject:content]; } } } return [directoryPaths copy]; } + (NSArray *)directoryPathsAtParentDirectory:(NSString *)parentDirectoryPath { NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL isDirectory = NO; NSMutableArray *directoryPaths = [[NSMutableArray alloc] init]; for (NSString *content in [self contentsAtParentDirectory:parentDirectoryPath]) { NSString *path = [NSString stringWithFormat:@"%@/%@", parentDirectoryPath, content]; if ([fileManager fileExistsAtPath:path isDirectory:&isDirectory]) { if (isDirectory) { [directoryPaths addObject:path]; } } } return [directoryPaths copy]; } + (NSArray *)fileNamesAtParentDirectoryPath:(NSString *)parentDirectoryPath { NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL isDirectory = NO; NSMutableArray *filePaths = [[NSMutableArray alloc] init]; for (NSString *content in [self contentsAtParentDirectory:parentDirectoryPath]) { NSString *path = [NSString stringWithFormat:@"%@/%@", parentDirectoryPath, content]; if ([fileManager fileExistsAtPath:path isDirectory:&isDirectory]) { if (!isDirectory) { [filePaths addObject:content]; } } } return [filePaths copy]; } + (NSArray *)filePathsAtParentDirectoryPath:(NSString *)parentDirectoryPath { NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL isDirectory = NO; NSMutableArray *filePaths = [[NSMutableArray alloc] init]; for (NSString *content in [self contentsAtParentDirectory:parentDirectoryPath]) { NSString *path = [NSString stringWithFormat:@"%@/%@", parentDirectoryPath, content]; if ([fileManager fileExistsAtPath:path isDirectory:&isDirectory]) { if (!isDirectory) { [filePaths addObject:path]; } } } return [filePaths copy]; } @end
参考资料如下:
About Files and Directories
NSFileManager Class Reference
NSBundle Class Reference