iOS-進(jìn)階整理01 - 沙盒機(jī)制和文件管理NSFileManger,文件對接NSFileHander

一、沙盒機(jī)制

1.什么是沙盒

通俗的說,就是將一個(gè)應(yīng)用程序的所有的非代碼文件放在一個(gè)文件夾里(沙盒),應(yīng)用程序只能從該文件系統(tǒng)讀取文件,不能去其他地方訪問。
每一個(gè)iOS應(yīng)用程序都會(huì)為自己創(chuàng)建一個(gè)文件系統(tǒng)目錄。這個(gè)獨(dú)立封閉、安全的空間,叫做沙盒。

2.打開模擬器的沙盒目錄

點(diǎn)擊finder----點(diǎn)擊菜單欄的前往----按住alt,出現(xiàn)了隱藏的資源庫選項(xiàng)----點(diǎn)擊資源庫----developer----CoreSimulator----Devices,然后發(fā)現(xiàn)這里有很多的一長串字母的文件,
根據(jù)時(shí)間找到最新的一個(gè)文件打開。
或者在終端寫 : defaults write com.apple.finder AppleShowAllFiles -bool true ,也可以顯示隱藏文件

看到里面有三個(gè)并列文件夾 Library,Documents,tmp

Document:
只有用戶生成的文件、其他數(shù)據(jù)及其他程序不能重新創(chuàng)建的文件,應(yīng)該保存在<Application_Home>/Documents 目錄下面,并將通過iCloud自動(dòng)備份,應(yīng)該將所有的應(yīng)用程序數(shù)據(jù)文件寫入到這個(gè)目錄下。
Library
iTunes不會(huì)自動(dòng)備份此目錄
這個(gè)目錄下有兩個(gè)子目錄:Caches 和 Preferences
Caches
可以重新下載或者重新生成的數(shù)據(jù)應(yīng)該保存在 <Application_Home>/Library/Caches 目錄下面。舉個(gè)例子,比如雜志、新聞、地圖應(yīng)用使用的數(shù)據(jù)庫緩存文件和可下載內(nèi)容應(yīng)該保存到這個(gè)文件夾。此目錄下不會(huì)再應(yīng)用退出時(shí)刪除。
Preferences
目錄包含應(yīng)用程序的偏好設(shè)置文件。您不應(yīng)該直接創(chuàng)建偏好設(shè)置文件,而是應(yīng)該使用NSUserDefaults類來取得和設(shè)置應(yīng)用程序的偏好
tmp
只是臨時(shí)使用的數(shù)據(jù)應(yīng)該保存到 <Application_Home>/tmp 文件夾。盡管 iCloud 不會(huì)備份這些文件,但在應(yīng)用在使用完這些數(shù)據(jù)之后要注意隨時(shí)刪除,避免占用用戶設(shè)備的空間,保存應(yīng)用程序再次啟動(dòng)過程中不需要的信息

二、文件的寫入與讀取

得到沙盒路徑的方法
寫在SandBoxPaths中,外部可調(diào)用

//得到docments路徑  
+(NSString *)documentsPath  
{  
    NSArray *docArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
    return docArray[0];  
}  
  
//library  
+(NSString *)libraryPath  
{  
    NSArray *libArray = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);  
    return libArray[0];  
}  
  
//library/cache  
+(NSString *)cachePath  
{  
    NSArray *cacheArray = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);  
    return cacheArray[0];  
}  
  
//library/perfrence 系統(tǒng)維護(hù)的,一般人為不會(huì)去動(dòng)這個(gè)文件夾  
+(NSString *)perfrencePath  
{  
    NSArray *perfrenceArr = NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory, NSUserDomainMask, YES);  
    return perfrenceArr[0];  
}  
  
//也可以通過拼接方式得到library/perfrence  
     
    NSArray *libPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);  
    NSLog(@"%@",libPath[0]);  
      
    NSString *perPath = [libPath[0]stringByAppendingString:@"Preferences"];  
      
//tmp路徑  
+(NSString *)tmpPath  
{  
    NSString *tmpStr = NSTemporaryDirectory();  
    return tmpStr;  
}  
  
   //app路徑  
    NSString *appPath = [NSBundle mainBundle].resourcePath;  
      
  //程序包中的一個(gè)圖片資源  
    NSString *imagePath = [[NSBundle mainBundle]pathForResource:@"myImage" ofType:@"png"];  
     ```

通過拼接方式獲得路徑

//沙盒主路徑
NSString *homeStrPath = NSHomeDirectory();
NSLog(@"homePath = %@",homeStrPath);

//得到沙盒下的lib路徑
NSString *libPath = [homeStrPath stringByAppendingPathComponent:@"Library"];
NSLog(@"lib : %@",libPath);

//得到沙盒下document路徑
NSString *docPath = [homeStrPath stringByAppendingPathComponent:@"Documents"];

寫入和讀取文件

//寫入文件
-(void)writeString
{
NSString *str = @"將要寫入的數(shù)據(jù)";

//拼接字符串,構(gòu)造數(shù)據(jù)將要存儲(chǔ)的位置  
NSString *path = [[SandBoxPaths documentsPath]stringByAppendingString:@"/text.txt"];  

//將數(shù)據(jù)寫入路徑下  
//核心方法writeToFile,可以寫入字符串,數(shù)組,字典等  
//atomically:YES,會(huì)先寫入一個(gè)中間臨時(shí)文件,完成后再存入目標(biāo)文件  
BOOL isWrite = [str writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];  
if (isWrite) {  
    NSLog(@"寫入成功,%@",path);  
}  
else  
    NSLog(@"寫入失敗");  

}

//讀取文件
-(void)readFile:(NSString*)path
{
//path的文件里面是什么格式,就用什么格式去取
//路徑就是定位到文件的路徑

//NSArray *arr = [NSArray arrayWithContentsOfFile:path];  
NSString *str = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];  
NSLog(@"讀?。?@",str);  

}

##三、文件管理器NSFileManger與文件對接器NSFileHandle,還有歸檔
#####1.文件管理器
文件管理器主要是對文件進(jìn)行創(chuàng)建、刪除、改名、獲取文件信息等操作
文件連接器主要對文件內(nèi)容進(jìn)行讀取和寫入

//FILEmanager使用
-(void)myFilemanager
{
//得到路徑
NSString* path = [[SandBoxPaths documentsPath]stringByAppendingPathComponent:@"test"];
NSString *pathTest = [[SandBoxPaths documentsPath]stringByAppendingPathComponent:@"text.txt"];
NSString *pathDst = [[SandBoxPaths documentsPath]stringByAppendingPathComponent:@"test/text1.txt"];
NSString *pathStrFile = [[SandBoxPaths documentsPath]stringByAppendingPathComponent:@"file.txt"];

NSString *str = @"sssssssssssss";  
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];              
//創(chuàng)建文件管理器  
NSFileManager *fileM = [NSFileManager defaultManager];  
  
//創(chuàng)建目錄  
//路徑Path  
//是否自動(dòng)創(chuàng)建  
//attributes權(quán)限設(shè)置  
BOOL isCreate = [fileM createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];  
  
if (isCreate) {  
    NSLog(@"成功:,%@",path);  
}  
else  
    NSLog(@"失敗");  
  
//創(chuàng)建文件并寫入數(shù)據(jù)  
[fileM createFileAtPath:pathStrFile contents: data attributes:nil];  

//從文件中讀取  
NSData *getData = [fileM contentsAtPath:pathStrFile];  
NSLog(@"%@",[[NSString alloc]initWithData:getData encoding:NSUTF8StringEncoding]);  
        
//移動(dòng)文件位置  
BOOL isMove = [fileM moveItemAtPath:pathTest toPath:pathDst error:nil];  
if (isMove) {  
    NSLog(@"成功移動(dòng)");  
}  
else  
    NSLog(@"移動(dòng)失敗");  
  
//復(fù)制文件  
BOOL isCopy = [fileM copyItemAtPath:pathDst toPath:pathTest error:nil];  
if (isCopy) {  
    NSLog(@"復(fù)制成功");  
}  
else  
    NSLog(@"復(fù)制失敗");  
  
//比較文件是否相同  
BOOL isEqual = [fileM contentsEqualAtPath:pathTest andPath:pathDst];  
if (isEqual) {  
    NSLog(@"文件內(nèi)容相同");  
}  
else  
    NSLog(@"文件內(nèi)容不同");  
  
//移除文件  
BOOL isRemove = [fileM removeItemAtPath:pathDst error:nil];  
if (isRemove) {  
    NSLog(@"移除成功");  
}  
else  
    NSLog(@"移除失敗");  
  
//文件是否存在  
BOOL isExist = [fileM fileExistsAtPath:pathDst];  
if (isExist) {  
    NSLog(@"文件存在");  
}  
else  
    NSLog(@"文件不存在");        

}

#####2.文件對接器,NSFileHandle

//NSfileHandle的使用
//首次使用時(shí),要先創(chuàng)建需要操作的文件
NSString *path = [[SandBoxPaths documentsPath]stringByAppendingPathComponent:@"fileHandele.txt"];
NSString *contentStr = @"12345678901234567890";
NSData *contentData = [contentStr dataUsingEncoding:NSUTF8StringEncoding];
NSFileManager *manager = [NSFileManager defaultManager];

//先判斷文件是否存在,如果不存在再創(chuàng)建
if ([manager fileExistsAtPath:path]) {
NSLog(@"文件已經(jīng)存在");
}
else
{
//創(chuàng)建文件
[manager createFileAtPath:path contents:contentData attributes:nil];
}

//創(chuàng)建準(zhǔn)備讀取的handle對象
NSFileHandle *readHandle =[NSFileHandle fileHandleForReadingAtPath:path];

//得到可讀的內(nèi)容的長度,節(jié)點(diǎn)移動(dòng)到末尾
NSUInteger length = [[readHandle availableData]length];
NSLog(@"%ld",length);

//跳到指定的偏移量
[readHandle seekToFileOffset:5];

//讀取特定長度,從當(dāng)前節(jié)點(diǎn)到指定長度,節(jié)點(diǎn)移動(dòng)到讀取末尾
NSData *lengthData = [readHandle readDataOfLength:11];
NSString *lengthStr = [[NSString alloc]initWithData:lengthData encoding:NSUTF8StringEncoding];
NSLog(@"lengthStr = %@",lengthStr);

//得到從當(dāng)前節(jié)點(diǎn)到最后的可讀取的內(nèi)容,節(jié)點(diǎn)移動(dòng)到最后
NSData *availableData = [readHandle availableData];
NSString *availableStr = [[NSString alloc]initWithData:availableData encoding:NSUTF8StringEncoding];
NSLog(@"avStr = %@",availableStr);

//跳到指定的偏移量,移動(dòng)回2處,也就是從第三個(gè)位置開始讀
[readHandle seekToFileOffset:2];

//完整的讀取文件,從當(dāng)前節(jié)點(diǎn)讀到末尾
NSData *endData = [readHandle readDataToEndOfFile];

NSString *endStr = [[NSString alloc]initWithData:endData encoding:NSUTF8StringEncoding];
NSLog(@"endStr = %@",endStr);

//創(chuàng)建一個(gè)可以寫入的fileHandle
NSFileHandle *writeHandle = [NSFileHandle fileHandleForWritingAtPath:path];
//改變偏移量
[writeHandle seekToFileOffset:4];
//寫入
NSString *writeStr = @"abc";
NSData *writeData = [writeStr dataUsingEncoding:NSUTF8StringEncoding];
[writeHandle writeData:writeData];

//跳到指定的偏移量
[readHandle seekToFileOffset:0];

//讀取
NSString *allStr = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSLog(@"allStr = %@",allStr);

#####3.歸檔與反歸檔
歸檔的作用,就是將復(fù)雜對象存儲(chǔ)進(jìn)文件,復(fù)雜對象就是如我們自己定義的person類,student類,不能用writeToFile寫入文件中。

我們需要先將復(fù)雜對象轉(zhuǎn)換為NSData類型,用writeToFile存入文件
取出時(shí)再通過反歸檔,把NSData類型恢復(fù)成復(fù)雜對象
歸檔時(shí),person類等要遵守<NSCoding>協(xié)議,實(shí)現(xiàn)歸檔和反歸檔的方法

import "Person.h"

@implementation Person

//序列化操作,歸檔
//實(shí)際上是對當(dāng)前類對象所有的屬性進(jìn)行歸檔
//協(xié)議方法在我們歸檔的時(shí)候自動(dòng)調(diào)用
-(void)encodeWithCoder:(NSCoder *)aCoder
{

[aCoder encodeObject:self.name forKey:@"name"];  
[aCoder encodeObject:self.sex forKey:@"sex"];  

}

//反歸檔
-(instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.sex = [aDecoder decodeObjectForKey:@"sex"];
}
return self;
}

pragma mark -- 歸檔,反歸檔

-(void)archiver
{
Person *firstPer = [[Person alloc]init];
firstPer.name = @"wna";
firstPer.sex = @"m";

//創(chuàng)建一個(gè)mutableData,用于保存歸檔后的對象  
NSMutableData *mutableData = [NSMutableData data];  
//創(chuàng)建歸檔工具  
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:mutableData];  
//歸檔  
[archiver encodeObject:firstPer forKey:@"person"];  
  
//結(jié)束  
//只有調(diào)用了此方法,才會(huì)將歸檔好的對象裝換為NSData  
[archiver finishEncoding];  
  
//拼接寫入沙盒路徑  
NSString *cachesPath2 = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)objectAtIndex:0]  
                        stringByAppendingPathComponent:@"person.txt"];  
//寫入沙盒  
[mutableData writeToFile:cachesPath2 atomically:YES];  

}

//反歸檔
-(void)unArchiver
{
//拼接寫入沙盒路徑
NSString *cachesPath2 = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)objectAtIndex:0]
stringByAppendingPathComponent:@"person.txt"];
//反歸檔
//從文件路徑讀取
NSData *fileData = [NSData dataWithContentsOfFile:cachesPath2];
//反歸檔工具
NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:fileData];
//反歸檔成對象,key要對應(yīng)
Person *secondPer = [unArchiver decodeObjectForKey:@"person"];
//反歸檔結(jié)束
[unArchiver finishDecoding];

NSLog(@"person = %@",secondPer.name);  

}

這里再附加一個(gè)把UIImage轉(zhuǎn)換為NSString的方法

//UIImage轉(zhuǎn)換為NSString
-(NSString)imageToStringWithImage:(UIImage)image
{
//先將image轉(zhuǎn)換為data類型,后面參數(shù)是品質(zhì)
NSData imageData = UIImageJPEGRepresentation(image, 1.0);
//再講NSData轉(zhuǎn)換為NSString
NSString string = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
return string;
}
//將base64的字符串轉(zhuǎn)換為圖片
-(UIImage
)base64StringToImage:(NSString
)base64Str
{
//將字符串轉(zhuǎn)換為NSData
NSData *imageData = [[NSData alloc]initWithBase64EncodedString:base64Str
options:NSDataBase64DecodingIgnoreUnknownCharacters];
//NSData到圖片
UIImage *image = [UIImage imageWithData:imageData];
return image;
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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