沙盒
iOS應(yīng)用程序只能在為該改程序創(chuàng)建的文件系統(tǒng)中讀取文件荡碾,不可以去其它地方訪問,此區(qū)域被成為沙盒盐须,所以所有的非代碼文件都要保存在此玩荠,例如圖像,圖標(biāo)贼邓,聲音阶冈,映像··,屬性列表塑径,文本文件等女坑。每個應(yīng)用程序都有自己的存儲空間,應(yīng)用程序不能翻過自己的圍墻去訪問別的存儲空間的內(nèi)容统舀,應(yīng)用程序請求的數(shù)據(jù)都要通過權(quán)限檢測匆骗,假如不符合條件的話劳景,不會被放行。
NSLog(@"沙盒文件路徑%@",NSHomeDirectory());
沙盒下有三個文件夾:
1.Documents:主要保存用戶的個人信息碉就,當(dāng)用戶重置手機配置時盟广,里邊的文件會被備份。
2.Library:里邊有兩個文件夾Caches和Preferences瓮钥,Caches里邊保存的文件不會在程序退出時清空筋量,但是重置手機配置是不會備份。Preferences里邊主要保存系統(tǒng)的單例NSUserDefaults.
3.tmp:主要保存一些程序的臨時文件碉熄。
通過主目錄得到Documents文件夾
//兩種拼接方式
NSString *documentPath = [NSHomeDirectory() stringByAppendingString:@"/Documents"];
NSString *documenPath1 = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
NSLog(@"%@\n%@",documentPath,documenPath1);
根據(jù)路徑找尋系統(tǒng)下相應(yīng)的文件 返回結(jié)果是一個路徑數(shù)組
//第一個參數(shù)為枚舉值桨武,枚舉值所對應(yīng)的是所要查詢的文件的路徑
//第二個參數(shù)為查詢的范圍
//第三個參數(shù)是個BOOL值,意思是詢問路徑中的~是否需要擴展
NSArray *documentsPathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(@"%@",[documentsPathArray firstObject]);
文件的寫入操作
文件的寫入只能寫入一些簡單的數(shù)據(jù)類型锈津,如字符串呀酸,數(shù)組,字典琼梆。不能寫入自定義的類性誉,自定義類的存儲需要用到歸檔和反歸檔。
字符串寫入:
- (void)writeDataToFiel
{
//將字符串寫入文件
NSString *string = @"我一會兒要進入一個文件夾";
//創(chuàng)建數(shù)據(jù)所要寫入的文件路徑
NSString *savePath = [NSHomeDirectory() stringByAppendingString:@"/Documents/test.txt"];
//寫入數(shù)據(jù)
//file:要寫入數(shù)據(jù)的文件路徑 atomically:保證數(shù)據(jù)的原子性茎杂,如果是YES艾栋,文件在寫入過程中是一部分一部分寫入,最后拼接為完整的數(shù)據(jù)蛉顽。 encoding:如果寫入為字符串類型,這個參數(shù)為字符的編碼格式先较,一般是UTF-8
[string writeToFile:savePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@",savePath);
}
數(shù)組的寫入:
- (void)writeArray
{
NSArray *array = @[@"152",@"afq",@"15asd"];
NSString *savePath = [NSHomeDirectory() stringByAppendingString:@"/Documents/0.txt"];
[array writeToFile:savePath atomically:YES];
}
文件的讀取
字符串讀刃:
- (void)readDataFromFiel
{
//要讀取文件的路徑
NSString *readPath = [NSHomeDirectory() stringByAppendingString:@"/Documents/test.txt"];
NSString *string = [NSString stringWithContentsOfFile:readPath encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@",string);
}
數(shù)組的讀取:
- (void)readArray
{
NSString *savePath = [NSHomeDirectory() stringByAppendingString:@"/Documents/0.txt"];
NSArray *array = [NSArray arrayWithContentsOfFile:savePath];
NSLog(@"%@",array);
// NSFileManager *fileManager = [[NSFileManager alloc] init];
// [fileManager removeItemAtPath:savePath error:nil];.
}
文件刪除
NSFileManager:文件管理類
NSFileManager *fileManager = [[NSFileManager alloc] init];
//savePath為所要刪除的文件的路徑
[fileManager removeItemAtPath:savePath error:nil];.
歸檔和反歸檔
歸檔:實際上就是將當(dāng)前類的屬性編碼為NSData類型
反歸檔:基礎(chǔ)類型,例如NSArray都有initWithContentsOfFile的方法來初始化闲勺,但是復(fù)雜類型沒有類似方法曾棕,因為歸檔過程中我們會將當(dāng)前類轉(zhuǎn)化為NSData類型,并且存儲到了某個文件中菜循,當(dāng)我們從文件中讀取出來數(shù)據(jù)的時候翘地,只能是反歸檔來完成初始化。
創(chuàng)建一個Person類癌幕,聲明三個屬性:name衙耕,gender,age
#import "Person.h"
@implementation Person
//歸檔
- (void)encodeWithCoder:(NSCoder *)aCoder
{
//實際的編碼過程勺远,原理就是將name這個屬性的值編碼為NSData類型橙喘,因為我們解碼的時候需要重新為該類屬性賦值,所以需要加標(biāo)記胶逢,也就是key
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.gender forKey:@"gender"];
[aCoder encodeInt:self.age forKey:@"age"];
NSLog(@"執(zhí)行了歸檔方法");
}
//反歸檔
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
//將剛才編碼為NSData類型的屬性厅瞎,又通過解碼方式變回原來的類型饰潜,上面編碼過程中,所賦給key值為何種名稱和簸,底下解碼得對應(yīng)上
self.name = [aDecoder decodeObjectForKey:@"name"];
self.gender = [aDecoder decodeObjectForKey:@"gender"];
self.age = [aDecoder decodeIntForKey:@"age"];
}
NSLog(@"執(zhí)行了反歸檔方法");
return self;
}
@end
使用Person將文件存入沙盒彭雾,創(chuàng)建一個視圖控制器,并且引入頭文件Person.h锁保。
#import "RootViewController.h"
#import "Person.h"
@interface RootViewController ()
@end
@implementation RootViewController
//歸檔并存入沙盒中
- (void)archiverAndSaveSandBox
{
//歸檔實際上就是將person對象轉(zhuǎn)換為NSData類型的數(shù)據(jù)
Person *person = [[Person alloc] init];
person.name = @"ly";
person.gender = @"男";
person.age = 23;
//歸檔的時候薯酝,實際上是將復(fù)雜類對象的屬性一一轉(zhuǎn)換為NSdata類型,所以是逐步轉(zhuǎn)換的身诺,最終需要將每一步轉(zhuǎn)換好的NSData類型組裝為一個完整的NSData蜜托,所以我們需要一個可變的NSData類型來接收它
NSMutableData *receiveData = [[NSMutableData alloc] init];
//歸檔操作需要借助系統(tǒng)的一個歸檔工具類來實現(xiàn),這個類實際操作就是將person對象轉(zhuǎn)換為NSData類型的數(shù)據(jù)霉赡,并賦值給初始化好的對象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:receiveData];
//歸檔開始
[archiver encodeObject:person forKey:@"person"];
//需要由一個標(biāo)志橄务,讓我們直到歸檔完成了,我們receiveData中有值了
[archiver finishEncoding];
//已經(jīng)轉(zhuǎn)換完成的穴亏,就可以進行數(shù)據(jù)持久化了
NSString *pathString = [NSHomeDirectory() stringByAppendingString:@"/Documents/person.DA"];
[receiveData writeToFile:pathString atomically:YES];
NSLog(@"%@",pathString);
}
//反歸檔
- (void)unArichiver
{
//反歸檔蜂挪,實際上就是將NSData類型轉(zhuǎn)換為復(fù)雜類型對象,就是本例中的person對象
NSString *pathString = [NSHomeDirectory() stringByAppendingString:@"/Documents/person.DA"];
NSData *data =[[NSData alloc] initWithContentsOfFile:pathString];
//反歸檔嗓化,需要借助系統(tǒng)類實現(xiàn)反歸檔過程
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
//開始反歸檔,這里要注意不是指針指向棠涮,實際上已經(jīng)初始化了
Person *person = [unarchiver decodeObjectForKey:@"person"];
NSLog(@"%@",person.name);
}
- (void)viewDidLoad {
[super viewDidLoad];
[self unArichiver];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end