[TOC]
相關(guān)知識
--
沙盒機(jī)制
每一個iOS應(yīng)用程序都會為自己創(chuàng)建一個文件系統(tǒng)目錄娃圆,這個獨(dú)立、封閉蛾茉、安全的空間叫做沙盒讼呢。沙盒就是一種安全體系,它規(guī)定了應(yīng)用程序只能在自己的文件系統(tǒng)目錄內(nèi)訪問文件谦炬,不可以訪問其他應(yīng)用沙盒內(nèi)的內(nèi)容悦屏。所有的非代碼文件都保存在這個地方节沦。
沙盒根目錄結(jié)構(gòu):Documents、Library础爬、temp
Documents
保存應(yīng)用運(yùn)行時生成的需要持久化的數(shù)據(jù)甫贯,iTunes備份和恢復(fù)的時候會包括此目錄,所以蘋果建議將程序中建立的或在程序中瀏覽到的文件數(shù)據(jù)保存在該目錄下看蚜。
Library
- Caches:存放緩存文件叫搁,iTunes不會備份此目錄,此目錄下文件不會在應(yīng)用退出后刪除 供炎。一般存放體積比較大渴逻,不是特別重要的資源。
- Preferences:保存APP的所有偏好設(shè)置音诫,iOS的Settings(設(shè)置)應(yīng)用會在該目錄中查找應(yīng)用的設(shè)置信息惨奕,iTunes會自動備份該目錄。注意:通過NSUserDefaults類來讀取和設(shè)置纽竣。
tmp
保存應(yīng)用運(yùn)行時所需的臨時數(shù)據(jù)墓贿,這個可以放一些當(dāng)APP退出后不再需要的文件。應(yīng)用沒有運(yùn)行時蜓氨,系統(tǒng)也有可能會清除該目錄下的文件聋袋,iTunes不會同步該目錄。iPhone重啟時穴吹,該目錄下的文件會被刪除幽勒。
如何查看該目錄?
XCode->Window->Devices->真機(jī)->Installed Apps->應(yīng)用->ShowContainer
也可以點(diǎn)擊DownloadContainer下載該沙盒文件查看內(nèi)容
獲取相關(guān)目錄
// 獲取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有系統(tǒng)維護(hù)啥容,所以我們很少去操作它。
NSString *preferPath = [LibraryPath stringByAppendingPathComponent:@"Preferences"];
// 獲取tmp目錄
NSString *tmpPath = NSTemporaryDirectory();
[toc]
相關(guān)文件操作
--
- 創(chuàng)建文件夾
+(BOOL)creatDir:(NSString *)path{
if (path.length==0) {
return NO;
}
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]);
}
}
return isSuccess;
}
- 創(chuàng)建文件
+(BOOL)creatFile:(NSString*)filePath{
if (filePath.length==0) {
return NO;
}
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:filePath]) {
return YES;
}
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) {
return isSuccess;
}
isSuccess = [fileManager createFileAtPath:filePath contents:nil attributes:nil];
return isSuccess;
}
- 寫數(shù)據(jù)
+(BOOL)writeToFile:(NSString*)filePath contents:(NSData *)data{
if (filePath.length==0) {
return NO;
}
BOOL result = [self creatFile:filePath];
if (result) {
if ([data writeToFile:filePath atomically:YES]) {
NSLog(@"write Success");
}else{
NSLog(@"write Failed");
}
}
else{
NSLog(@"write Failed");
}
return result;
}
- 追加寫數(shù)據(jù)
+(BOOL)appendData:(NSData*)data withPath:(NSString *)filePath{
if (filePath.length==0) {
return NO;
}
BOOL result = [self creatFile:filePath];
if (result) {
NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:filePath];
[handle seekToEndOfFile];
[handle writeData:data];
[handle synchronizeFile];
[handle closeFile];
}
else{
NSLog(@"appendData Failed");
}
return result;
}
- 讀文件數(shù)據(jù)
+(NSData*)readFileData:(NSString *)path{
NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
NSData *fileData = [handle readDataToEndOfFile];
[handle closeFile];
return fileData;
}
- 獲取文件夾下所有的文件列表
+(NSArray*)getFileList:(NSString*)path{
if (path.length==0) {
return nil;
}
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *fileList = [fileManager contentsOfDirectoryAtPath:path error:&error];
if (error) {
NSLog(@"getFileList Failed:%@",[error localizedDescription]);
}
return fileList;
}
- 獲取文件夾下所有文件(深度遍歷)
+(NSArray*)getAllFileList:(NSString*)path{
if (path.length==0) {
return nil;
}
NSArray *fileArray = [self getFileList:path];
NSMutableArray *fileArrayNew = [NSMutableArray array];
NSFileManager *fileManager = [NSFileManager defaultManager];
for (NSString *aPath in fileArray) {
NSString * fullPath = [path stringByAppendingPathComponent:aPath];
BOOL isDir = NO;
if ([fileManager fileExistsAtPath:fullPath isDirectory:&isDir]) {
if (isDir) {
[fileArrayNew addObjectsFromArray:[self getAllFileList:fullPath]];
}else{
[fileArrayNew addObject:fullPath];
}
}
}
return fileArrayNew;
}
- 移動文件
+(BOOL)moveFile:(NSString *)fromPath toPath:(NSString *)toPath toPathIsDir:(BOOL)dir{
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:fromPath]) {
NSLog(@"Error: fromPath Not Exist");
return NO;
}
BOOL isDir = NO;
BOOL isExist = [fileManager fileExistsAtPath:toPath isDirectory:&isDir];
if (isExist) {
if (isDir) {
if ([self creatDir:toPath]) {
NSString *fileName = fromPath.lastPathComponent;
toPath = [toPath stringByAppendingPathComponent:fileName];
return [self moveItemAtPath:fromPath toPath:toPath];
}
}else{
[self removeFile:toPath];
return [self moveItemAtPath:fromPath toPath:toPath];
}
}
else{
if (dir) {
if ([self creatDir:toPath]) {
NSString *fileName = fromPath.lastPathComponent;
toPath = [toPath stringByAppendingPathComponent:fileName];
return [self moveItemAtPath:fromPath toPath:toPath];
}
}else{
return [self moveItemAtPath:fromPath toPath:toPath];
}
}
return NO;
}
+(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]);
}
return result;
}
- 刪除文件
+(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");
}
return isSuccess;
}
- 刪除文件夾
+(BOOL)removeDir:(NSString*)path{
return [self removeFile:path];
}
- 刪除某些后綴的文件
+(void)removeFileSuffixList:(NSArray<NSString*>*)suffixList filePath:(NSString*)path deep:(BOOL)deep{
NSArray *fileArray = nil;
if (deep) { // 是否深度遍歷
fileArray = [self getAllFileList:path];
}else{
fileArray = [self getFileList:path];
NSMutableArray *fileArrayTmp = [NSMutableArray array];
for (NSString *fileName in fileArray) {
NSString* allPath = [path stringByAppendingPathComponent:fileName];
[fileArrayTmp addObject:allPath];
}
fileArray = fileArrayTmp;
}
for (NSString *aPath in fileArray) {
for (NSString* suffix in suffixList) {
if ([aPath hasSuffix:suffix]) {
[self removeFile:aPath];
}
}
}
}
- 獲取文件大小
+(long long)getFileSize:(NSString*)path{
unsigned long long fileLength = 0;
NSNumber *fileSize;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:path error:nil];
if ((fileSize = [fileAttributes objectForKey:NSFileSize])) {
fileLength = [fileSize unsignedLongLongValue]; //單位是 B
}
return fileLength;
}
- 獲取文件的信息(包含了上面文件大小)
+(NSDictionary*)getFileInfo:(NSString*)path{
NSError *error;
NSDictionary *reslut = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:&error];
if (error) {
NSLog(@"getFileInfo Failed:%@",[error localizedDescription]);
}
return reslut;
}
[toc]
NSFileManager和NSFileHandle
1顷霹、NSFileManager(文件管理對象)
主要是對文件進(jìn)行的操作(創(chuàng)建/刪除/改名等)以及文件信息的獲取咪惠。
方法 | 說明 |
---|---|
@property (class, readonly, strong) NSFileManager *defaultManager | 創(chuàng)建文件管理對象 |
-(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 | 創(chuàng)建一個目錄 |
-(BOOL)createFileAtPath:(NSString *)path contents:(nullable NSData *)data attributes:(nullable NSDictionary<NSString *, id> *)attr | 創(chuàng)建一個文件,可順便寫入data |
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile | NSData類型的寫入數(shù)據(jù),讀數(shù)據(jù)請自行查閱 |
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error | NSString遥昧、NSArray、NSDictionary的寫入數(shù)據(jù)朵纷,讀數(shù)據(jù)請自行查閱 |
-(nullable NSArray<NSString *> *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error | 獲取當(dāng)前文件夾下的文件/目錄 |
-(BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error | 移動文件炭臭,可用來重命名 |
-(BOOL)copyItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error | 復(fù)制文件 |
-(BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error | 刪除文件 |
-(nullable NSDictionary<NSFileAttributeKey, id> *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error | 獲取文件信息(文件大小、修改時間袍辞、所有者等) |
</b>
2鞋仍、NSFileHandle(文件連接器)
主要是對文件內(nèi)容進(jìn)行讀取和寫入操作
方法 | 說明 |
---|---|
+(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 | 將文件的長度設(shè)為offset字節(jié) |
-(NSData *)readDataToEndOfFile | 從當(dāng)前字節(jié)讀取到文件到末尾數(shù)據(jù) |
-(NSData *)readDataOfLength:(NSUInteger)length | 從當(dāng)前字節(jié)讀取到指定長度數(shù)據(jù) |
-(void)synchronizeFile | 同步文件,通常用在寫入數(shù)據(jù)后 |
-(void)closeFile | 關(guān)閉文件 |
[toc]
對象等復(fù)雜類型的讀寫操作
上述數(shù)據(jù)操作搅吁,支持的類型僅僅是NSString威创、NSArray落午、NSDictionary、NSData類型那婉,這些都數(shù)據(jù)類型都支持了NSCoding協(xié)議板甘,可以進(jìn)行數(shù)據(jù)持久化。如果我們想存儲如UIImage详炬、自定義的對象等類型盐类,我們都需要將其轉(zhuǎn)換為NSData類型,如轉(zhuǎn)換UIImage為NSData使用UIImagePNGRepresentation(image)等方法呛谜,而自定義對象類型則需要進(jìn)行歸檔在跳、反歸檔來進(jìn)行存取操作
存:
對象->歸檔->NSData->文件寫入
取:
文件讀取->NSData->反歸檔->對象
自定義對象需要遵守NSCoding協(xié)議并實現(xiàn)
- (void)encodeWithCoder:(NSCoder *)aCoder; //序列化
- (id)initWithCoder:(NSCoder *)aDecoder; //反序列化
兩個方法
[toc]