参考链接:https://www.jianshu.com/p/086ca6d2c5de
1.沙盒机制
处于安全考虑,iOS系统的沙盒机制规定每个应用都只能访问当前沙盒目录下面的文件(也有例外,比如在用户授权情况下访问通讯录,相册等),这个规则展示了iOS系统的封闭性。在开发中常常需要数据存储的功能,比如存取文件,归档解档等。
每一个iOS应用程序都会为自己创建一个文件系统目录,这个独立、封闭、安全的空间叫做沙盒。沙盒就是一种安全体系,它规定了应用程序只能在自己的文件系统目录内访问文件,不可以访问其他应用沙盒内的内容。所有的非代码文件都保存在这个地方。
沙盒根目录结构:Documents、Library、temp
沙盒目录
Documents
保存应用运行时生成的需要持久化的数据,iTunes备份和恢复的时候会包括此目录,所以苹果建议将程序中建立的或在程序中浏览到的文件数据保存在该目录下。
Library
Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出后删除 。一般存放体积比较大,不是特别重要的资源。
Preferences:保存APP的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找应用的设置信息,iTunes会自动备份该目录。注意:通过NSUserDefaults类来读取和设置。
tmp
保存应用运行时所需的临时数据,这个可以放一些当APP退出后不再需要的文件。应用没有运行时,系统也有可能会清除该目录下的文件,iTunes不会同步该目录。iPhone重启时,该目录下的文件会被删除。
如何查看该目录?
XCode->Window->Devices->真机->Installed Apps->应用->ShowContainer
沙盒目录
也可以点击DownloadContainer下载该沙盒文件查看内容
沙盒内容
获取相关目录
// 获取Document目录NSString*docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)lastObject];// 获取Library目录NSString*LibraryPath=[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask,YES)lastObject];// 获取Caches目录NSString*cachesPath=[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES)lastObject];// 获取Preferences目录 通常情况下,Preferences有系统维护,所以我们很少去操作它。NSString*preferPath=[LibraryPath stringByAppendingPathComponent:@"Preferences"];// 获取tmp目录NSString*tmpPath=NSTemporaryDirectory();
说明:
三、NSSearchPathForDirectoriesInDomains
NSSearchPathForDirectoriesInDomains方法用于查找目录,返回指定范围内的指定名称的目录的路径集合。有三个参数:
**directory** NSSearchPathDirectory类型的enum值,表明我们要搜索的目录名称,比如这里用NSDocumentDirectory表明我们要搜索的是Documents目录。如果我们将其换成NSCachesDirectory就表示我们搜索的是Library/Caches目录。
** * domainMask* ** NSSearchPathDomainMask类型的enum值,指定搜索范围,这里的NSUserDomainMask表示搜索的范围限制于当前应用的沙盒目录。还可以写成NSLocalDomainMask(表示/Library)、NSNetworkDomainMask(表示/Network)等。
** * expandTilde* ** BOOL值,表示是否展开波浪线。我们知道在iOS中的全写形式是/User/userName,该值为YES即表示写成全写形式,为NO就表示直接写成“~”。
该值为NO:Caches目录路径~/Library/Caches
该值为YES:Caches目录路径
/var/mobile/Containers/Data/Application/E7B438D4-0AB3-49D0-9C2C-B84AF67C752B/Library/Caches
[toc]
相关文件操作
--
创建文件夹
+(BOOL)creatDir:(NSString*)path{if(path.length==0){returnNO;}NSFileManager*fileManager=[NSFileManager defaultManager];BOOL isSuccess=YES;BOOL isExist=[fileManager fileExistsAtPath:path];if(isExist==NO){NSError*error;if(![fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]){isSuccess=NO;NSLog(@"creat Directory Failed:%@",[error localizedDescription]);}}returnisSuccess;}
创建文件
+(BOOL)creatFile:(NSString*)filePath{if(filePath.length==0){returnNO;}NSFileManager*fileManager=[NSFileManager defaultManager];if([fileManager fileExistsAtPath:filePath]){returnYES;}NSError*error;NSString*dirPath=[filePath stringByDeletingLastPathComponent];BOOL isSuccess=[fileManager createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:&error];if(error){NSLog(@"creat File Failed:%@",[error localizedDescription]);}if(!isSuccess){returnisSuccess;}isSuccess=[fileManager createFileAtPath:filePath contents:nil attributes:nil];returnisSuccess;}
写数据
+(BOOL)writeToFile:(NSString*)filePath contents:(NSData*)data{if(filePath.length==0){returnNO;}BOOL result=[selfcreatFile:filePath];if(result){if([data writeToFile:filePath atomically:YES]){NSLog(@"write Success");}else{NSLog(@"write Failed");}}else{NSLog(@"write Failed");}returnresult;}
追加写数据
+(BOOL)appendData:(NSData*)data withPath:(NSString*)filePath{if(filePath.length==0){returnNO;}BOOL result=[selfcreatFile:filePath];if(result){NSFileHandle*handle=[NSFileHandle fileHandleForWritingAtPath:filePath];[handle seekToEndOfFile];[handle writeData:data];[handle synchronizeFile];[handle closeFile];}else{NSLog(@"appendData Failed");}returnresult;}
读文件数据
+(NSData*)readFileData:(NSString*)path{NSFileHandle*handle=[NSFileHandle fileHandleForReadingAtPath:path];NSData*fileData=[handle readDataToEndOfFile];[handle closeFile];returnfileData;}
获取文件夹下所有的文件列表
+(NSArray*)getFileList:(NSString*)path{if(path.length==0){returnnil;}NSFileManager*fileManager=[NSFileManager defaultManager];NSError*error;NSArray*fileList=[fileManager contentsOfDirectoryAtPath:path error:&error];if(error){NSLog(@"getFileList Failed:%@",[error localizedDescription]);}returnfileList;}
获取文件夹下所有文件(深度遍历)
+(NSArray*)getAllFileList:(NSString*)path{if(path.length==0){returnnil;}NSArray*fileArray=[selfgetFileList:path];NSMutableArray*fileArrayNew=[NSMutableArray array];NSFileManager*fileManager=[NSFileManager defaultManager];for(NSString*aPathinfileArray){NSString*fullPath=[path stringByAppendingPathComponent:aPath];BOOL isDir=NO;if([fileManager fileExistsAtPath:fullPath isDirectory:&isDir]){if(isDir){[fileArrayNew addObjectsFromArray:[selfgetAllFileList:fullPath]];}else{[fileArrayNew addObject:fullPath];}}}returnfileArrayNew;}
移动文件
+(BOOL)moveFile:(NSString*)fromPath toPath:(NSString*)toPath toPathIsDir:(BOOL)dir{NSFileManager*fileManager=[NSFileManager defaultManager];if(![fileManager fileExistsAtPath:fromPath]){NSLog(@"Error: fromPath Not Exist");returnNO;}BOOL isDir=NO;BOOL isExist=[fileManager fileExistsAtPath:toPath isDirectory:&isDir];if(isExist){if(isDir){if([selfcreatDir:toPath]){NSString*fileName=fromPath.lastPathComponent;toPath=[toPath stringByAppendingPathComponent:fileName];return[selfmoveItemAtPath:fromPath toPath:toPath];}}else{[selfremoveFile:toPath];return[selfmoveItemAtPath:fromPath toPath:toPath];}}else{if(dir){if([selfcreatDir:toPath]){NSString*fileName=fromPath.lastPathComponent;toPath=[toPath stringByAppendingPathComponent:fileName];return[selfmoveItemAtPath:fromPath toPath:toPath];}}else{return[selfmoveItemAtPath:fromPath toPath:toPath];}}returnNO;}+(BOOL)moveItemAtPath:(NSString*)fromPath toPath:(NSString*)toPath{BOOL result=NO;NSError*error=nil;NSFileManager*fileManager=[NSFileManager defaultManager];result=[fileManager moveItemAtPath:fromPath toPath:toPath error:&error];if(error){NSLog(@"moveFile Fileid:%@",[error localizedDescription]);}returnresult;}
删除文件
+(BOOL)removeFile:(NSString*)filePath{BOOL isSuccess=NO;NSError*error;NSFileManager*fileManager=[NSFileManager defaultManager];isSuccess=[fileManager removeItemAtPath:filePath error:&error];if(error){NSLog(@"removeFile Field:%@",[error localizedDescription]);}else{NSLog(@"removeFile Success");}returnisSuccess;}
删除文件夹
+(BOOL)removeDir:(NSString*)path{return[selfremoveFile:path];}
删除某些后缀的文件
+(void)removeFileSuffixList:(NSArray<NSString*>*)suffixList filePath:(NSString*)path deep:(BOOL)deep{NSArray*fileArray=nil;if(deep){// 是否深度遍历fileArray=[selfgetAllFileList:path];}else{fileArray=[selfgetFileList:path];NSMutableArray*fileArrayTmp=[NSMutableArray array];for(NSString*fileNameinfileArray){NSString*allPath=[path stringByAppendingPathComponent:fileName];[fileArrayTmp addObject:allPath];}fileArray=fileArrayTmp;}for(NSString*aPathinfileArray){for(NSString*suffixinsuffixList){if([aPath hasSuffix:suffix]){[selfremoveFile:aPath];}}}}
获取文件大小
+(longlong)getFileSize:(NSString*)path{unsignedlonglongfileLength=0;NSNumber*fileSize;NSFileManager*fileManager=[NSFileManager defaultManager];NSDictionary*fileAttributes=[fileManager attributesOfItemAtPath:path error:nil];if((fileSize=[fileAttributes objectForKey:NSFileSize])){fileLength=[fileSize unsignedLongLongValue];//单位是 B}returnfileLength;}
获取文件的信息(包含了上面文件大小)
+(NSDictionary*)getFileInfo:(NSString*)path{NSError*error;NSDictionary*reslut=[[NSFileManager defaultManager]attributesOfItemAtPath:path error:&error];if(error){NSLog(@"getFileInfo Failed:%@",[error localizedDescription]);}returnreslut;}
[toc]
NSFileManager和NSFileHandle
1、NSFileManager(文件管理对象)
主要是对文件进行的操作(创建/删除/改名等)以及文件信息的获取。
方法说明
@property (class, readonly, strong) NSFileManager *defaultManager创建文件管理对象
-(BOOL)fileExistsAtPath:(NSString *)path isDirectory:(nullable BOOL *)isDirectory判断某个路径是否存在,isDirectory是一个指针,表示该路径是否是目录
-(BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(nullable NSDictionary<NSString *, id> *)attributes error:(NSError **)error创建一个目录
-(BOOL)createFileAtPath:(NSString *)path contents:(nullable NSData *)data attributes:(nullable NSDictionary<NSString *, id> *)attr创建一个文件,可顺便写入data
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFileNSData类型的写入数据,读数据请自行查阅
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)errorNSString、NSArray、NSDictionary的写入数据,读数据请自行查阅
-(nullable NSArray<NSString *> *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error获取当前文件夹下的文件/目录
-(BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error移动文件,可用来重命名
-(BOOL)copyItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error复制文件
-(BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error删除文件
-(nullable NSDictionary<NSFileAttributeKey, id> *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error获取文件信息(文件大小、修改时间、所有者等)
</b>
2、NSFileHandle(文件连接器)
主要是对文件内容进行读取和写入操作
方法说明
+(nullable instancetype)fileHandleForWritingAtPath:(NSString *)path写的方式打开文件
+(nullable instancetype)fileHandleForReadingAtPath:(NSString *)path读的方式打开文件
-(unsigned long long)seekToEndOfFile跳到文件末尾
-(void)seekToFileOffset:(unsigned long long)offset跳到指定偏移位置
-(void)truncateFileAtOffset:(unsigned long long)offset将文件的长度设为offset字节
-(NSData *)readDataToEndOfFile从当前字节读取到文件到末尾数据
-(NSData *)readDataOfLength:(NSUInteger)length从当前字节读取到指定长度数据
-(void)synchronizeFile同步文件,通常用在写入数据后
-(void)closeFile关闭文件
[toc]
对象等复杂类型的读写操作
上述数据操作,支持的类型仅仅是NSString、NSArray、NSDictionary、NSData类型,这些都数据类型都支持了NSCoding协议,可以进行数据持久化。如果我们想存储如UIImage、自定义的对象等类型,我们都需要将其转换为NSData类型,如转换UIImage为NSData使用UIImagePNGRepresentation(image)等方法,而自定义对象类型则需要进行归档、反归档来进行存取操作
存:
对象->归档->NSData->文件写入
取:
文件读取->NSData->反归档->对象
自定义对象需要遵守NSCoding协议并实现
-(void)encodeWithCoder:(NSCoder*)aCoder;//序列化 -(id)initWithCoder:(NSCoder*)aDecoder;//反序列化
两个方法