創(chuàng)建文件夾、創(chuàng)建文件、文件夾里面創(chuàng)建文件
一.幾種沙盒常用的存儲(chǔ)方式
1. 項(xiàng)目中常用的NSUserDefaults存放的地址是:Library/Preferences,里面以bundleId為名的偏好設(shè)置plist文件里面;
Library/Preferences包含應(yīng)用程序的偏好設(shè)置文件,您不應(yīng)該直接創(chuàng)建偏好設(shè)置文件,而是應(yīng)該使用NSUserDefaults類來取得和設(shè)置應(yīng)用程序的偏好。
2. 在使用plist進(jìn)行數(shù)據(jù)存儲(chǔ)和讀取,只適用于系統(tǒng)自帶的一些常用類型才能用,且必須先獲取路徑相對(duì)麻煩;
3. 歸檔:因?yàn)殚g接(NSUserDefaults)或者直接操作使用plist文件,只能存儲(chǔ)常用的類型, 而歸檔可以實(shí)現(xiàn)把自定義的對(duì)象存放在文件中。
二. 存取的方式
通常用fileManager寫入的例如頁面信息等大量緩存等存放地址是:Library/Caches; 寫入的運(yùn)行過程產(chǎn)生的如用戶信息等需要持久化的數(shù)據(jù),可以寫入document。
NSUserDefaults直接寫入后,是默認(rèn)存放在系統(tǒng)偏好設(shè)置的plist文件(registerDefaults方法除外,它沒有寫入plist)。
fileManager寫入:
1. 先創(chuàng)建路徑(也就文件夾路徑):
NSFileManager *fileM = [NSFileManager defaultManager];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"wgj01"];
if (![fileM fileExistsAtPath:documentsPath]) {
[fileM createDirectoryAtPath:documentsPath withIntermediateDirectories:YES attributes:nil error:nil];
}
2. 寫入方式一:
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"w"];
NSDictionary *dict = @{@"w":@"wwww"};
[dict writeToFile:filePath atomically:YES];
這樣寫入之后,在NSCachesDirectory里面的wgj01文件夾中有一個(gè)w文件,因?yàn)闆]有后綴,所以存放格式為xml格式。
3. 寫入方式二:
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"ws.plist"];
NSDictionary *dict = @{@"w":@"wwww"};
[dict writeToFile:filePath atomically:YES];
文件ws有后綴,寫入的是plist格式。
3.1 針對(duì)3 的讀取&修改方式:
//讀?。? NSString *filePath = [documentsPath stringByAppendingPathComponent:@"ws.plist"];
NSMutableDictionary *dataDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
NSLog(@"\n\n\n%@",dataDict);
//修改或添加:
[dataDict setObject:@"mmmmm" forKey:@"m"];
[dataDict writeToFile:filePath atomically:YES];
3.2 對(duì)于項(xiàng)目文件中的plist文件:
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"wgjTT" ofType:@"plist"];
和沙盒里面的plist文件(上面3.1)一樣,對(duì)解析出來的字典或者數(shù)組進(jìn)行增刪改等操作,
但是,操作后,點(diǎn)擊查看plist文件,發(fā)現(xiàn)沒有變化,而,打印:
NSMutableDictionary *dataDictafter = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath1];
NSLog(@"\n\n\nTT0:\ndataDictafter:\n%@",dataDictafter);
發(fā)現(xiàn),打印結(jié)果時(shí)改變后的結(jié)果。
猜測(cè):應(yīng)該是只寫入了緩存,等程序重新運(yùn)行,打印plist數(shù)據(jù)結(jié)果還是修改前的結(jié)果(plist并未有實(shí)質(zhì)性的改變)。
4. 寫入方式三:
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"wh"];
NSDictionary *dict = @{@"w":@"wwww"};
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
[fileM createFileAtPath:filePath contents:data attributes:nil];
這樣,在wgj01文件夾下有一個(gè)wh文件,它里面的格式為:json格式。
eg.
{
"w" : "wwww"
}
4.1 針對(duì)4的讀出方式:
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"wh"];
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSDictionary *object11 = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableContainers) error:nil];
NSLog(@"\n\n\n%@",object11); //讀取成功
5. 若想要繼續(xù)創(chuàng)建文件夾,用stringByAppendingPathComponent后面拼接文件夾名稱 并且 用 if (![fileM fileExistsAtPath:documentsPath]) {
[fileM createDirectoryAtPath:documentsPath withIntermediateDirectories:YES attributes:nil error:nil];
}創(chuàng)建文件夾。
沙盒路徑各目錄用途:
Documents 目錄:您應(yīng)該將所有de應(yīng)用程序數(shù)據(jù)文件寫入到這個(gè)目錄下。這個(gè)目錄用于存儲(chǔ)用戶數(shù)據(jù)或其它應(yīng)該定期備份的信息。
AppName.app 目錄:這是應(yīng)用程序的程序包目錄,包含應(yīng)用程序的本身。由于應(yīng)用程序必須經(jīng)過簽名,所以您在運(yùn)行時(shí)不能對(duì)這個(gè)目錄中的內(nèi)容進(jìn)行修改,否則可能會(huì)使應(yīng)用程序無法啟動(dòng)。
Library 目錄:這個(gè)目錄下有兩個(gè)子目錄:Caches 和 Preferences
Library/Preferences 目錄:包含應(yīng)用程序的偏好設(shè)置文件。您不應(yīng)該直接創(chuàng)建偏好設(shè)置文件,而是應(yīng)該使用NSUserDefaults類來取得和設(shè)置應(yīng)用程序的偏好.
Library/Caches 目錄:用于存放應(yīng)用程序?qū)S玫闹С治募?,保存?yīng)用程序再次啟動(dòng)過程中需要的信息。
tmp 目錄:這個(gè)目錄用于存放臨時(shí)文件,保存應(yīng)用程序再次啟動(dòng)過程中不需要的信息。
1 應(yīng)用程序包:包含所有資源文件和可執(zhí)行文件
2 Documents:保存應(yīng)用運(yùn)行時(shí)生成的需要持久化的數(shù)據(jù),iTunes會(huì)自動(dòng)備份該目錄
3 tmp:保存應(yīng)用運(yùn)行時(shí)所需的臨時(shí)數(shù)據(jù),使用完畢后再將相應(yīng)的文件從該目錄刪除,應(yīng)用沒有運(yùn)行時(shí),系統(tǒng)也可能會(huì)自動(dòng)清理該目錄下的文件,iTunes不會(huì)同步該目錄,iPhone重啟時(shí)該目錄下的文件會(huì)丟失。
4 Libaray:存儲(chǔ)程序的默認(rèn)設(shè)置和其他狀態(tài)信息,iTunes會(huì)自動(dòng)備份該目錄。
5 Libaray/Caches:存放緩存文件,iTunes不會(huì)備份此目錄,此目錄下文件不會(huì)在應(yīng)用退出刪除,一般存放體積比較大,不是很重要的資源
6 Libaray/Preferences:保存應(yīng)用的所有偏好設(shè)置,ios的Settings(設(shè)置)應(yīng)用會(huì)在該目錄中查找應(yīng)用的設(shè)置信息,iTunes會(huì)自動(dòng)備份該目錄。
沙盒路徑地址的獲?。?/p>
1,獲取家目錄路徑的函數(shù):
NSString *homeDir = NSHomeDirectory();
2,獲取Documents目錄路徑的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
3,獲取Caches目錄路徑的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDir = [paths objectAtIndex:0];
4,獲取tmp目錄路徑的方法:
NSString *tmpDir = NSTemporaryDirectory();
5,獲取應(yīng)用程序程序包中資源文件路徑的方法:
例如獲取程序包中一個(gè)圖片資源(apple.png)路徑的方法:
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@”apple” ofType:@”png”];
UIImage *appleImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
代碼中的mainBundle類方法用于返回一個(gè)代表應(yīng)用程序包的對(duì)象。
e.g.
NSString *Path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSLog(@"目錄:%@",Path);
NSString *dataStr1 = @"testdata";
NSString *dataStr2 = @"wgjwgj";
NSString *dataStr3 = @"umeng";
NSData *data1 = [dataStr1 dataUsingEncoding:NSUTF8StringEncoding];
NSData *data2 = [dataStr2 dataUsingEncoding:NSUTF8StringEncoding];
NSData *data3 = [dataStr3 dataUsingEncoding:NSUTF8StringEncoding];
NSString *path1 = [Path stringByAppendingPathComponent:@"wgjTest1"];
NSString *path2 = [Path stringByAppendingPathComponent:@"wgjTest2"];
NSString *path4 = [Path stringByAppendingPathComponent:@"wgjjm"];
NSFileManager *fileManager1 = [NSFileManager defaultManager];
//創(chuàng)建文件夾
[fileManager1 createDirectoryAtPath:path4 withIntermediateDirectories:YES attributes:nil error:nil];
//創(chuàng)建文件
[fileManager1 createFileAtPath:path1 contents:data1 attributes:nil];
[fileManager1 createFileAtPath:path2 contents:data2 attributes:nil];
//文件夾里面創(chuàng)建文件
NSString *path5 = [path4 stringByAppendingPathComponent:@"wgj5"];
[fileManager1 createFileAtPath:path5 contents:data3 attributes:nil];
NSURL *url = [NSURL fileURLWithPath:Path isDirectory:YES];
//遍歷url這個(gè)相應(yīng)的目錄下的文件和文件夾以及文件夾中的文件,得出文件夾/文件目錄,和文件大小
NSDirectoryEnumerator *fileEnumerator = [fileManager1 enumeratorAtURL:url
includingPropertiesForKeys:@[NSFileSize]
options:NSDirectoryEnumerationSkipsHiddenFiles
errorHandler:NULL];
NSUInteger fileCount = 0;
NSUInteger totalSize = 0;
for (NSURL *fileURL in fileEnumerator) {
NSNumber *fileSize;
[fileURL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:NULL];
totalSize += fileSize.unsignedIntegerValue;
fileCount += 1;
}
YYModel的yy_modelEncodeWithCoder和yy_modelInitWithCoder
1. 當(dāng)自己實(shí)現(xiàn)歸檔archive的時(shí)候,需要實(shí)現(xiàn)<NSCoding>協(xié)議encode和code方法,并且需要把類里面的所有屬性在encode和code方法中全部羅列操作一遍,很是麻煩,所以就可以使用YYModel的歸檔;
2. YYModel實(shí)現(xiàn)歸檔主要點(diǎn):
a. 把屬性分為幾種類型,它把int bool等數(shù)值類型都轉(zhuǎn)為了NSNumber類型并使用encodeObject:forKey: 直接當(dāng)成object處理。
b. 把類對(duì)象的結(jié)構(gòu)直接映射拿了出來,并映射到Y(jié)Y自己自定義的結(jié)構(gòu),之后循環(huán)判斷此類和父類一直向上找,取出所有的屬性并操作賦值。此取出屬性,包括了類所有父類的自定義屬性。
c. 通過objc_property_attribute_t獲取成員變量的類型,并通過字符判斷具體類型返回類型枚舉以供使用。
MJModel的mj_decode和mj_encode
1. 其實(shí)mj的encode原理和YY的差不多,只不過,mj只是利用的objc_property_t的runtime方法,沒有自定義和系統(tǒng)類相似的結(jié)構(gòu)做映射;也是循環(huán)類的諸多父類,找出所有的自定義屬性。
2. 因?yàn)闆]有做結(jié)構(gòu)體的映射,所以表面看起來稍微簡(jiǎn)單些。
3. 在encode的時(shí)候,也是把數(shù)值布爾等類型轉(zhuǎn)化為NSNumber類型,進(jìn)行encodeObject;具體做法是根據(jù)方法property_getAttributes,獲取類型字符串然后截取,如果是q或者i等等數(shù)值類型,就歸為NSNumber。
NSKeyedArchiver
- 對(duì)單個(gè)對(duì)象歸檔解擋
方式a. 歸: NSData *arData = [NSKeyedArchiver archivedDataWithRootObject:model1];
[arData writeToFile:path1 atomically:YES];
解: NSData *resultData = [NSData dataWithContentsOfFile:path1];
id result = [NSKeyedUnarchiver unarchiveObjectWithData:resultData];
方式b. 歸:BOOL isSuccess = [NSKeyedArchiver archiveRootObject:model1 toFile:path1];
解:id result = [NSKeyedUnarchiver unarchiveObjectWithFile:path1];
- 對(duì)多個(gè)對(duì)象歸檔解擋
1. 歸: NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archive1 = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archive1 encodeObject:@"13223432342" forKey:@"111"];
[archive1 encodeObject:model forKey:@"222"];
[archive1 finishEncoding];
BOOL is1 = [data writeToFile:path1 atomically:YES];
解: NSData *data2 = [NSData dataWithContentsOfFile:path1];
NSKeyedUnarchiver *archive2 = [[NSKeyedUnarchiver alloc] initForReadingWithData:data2];
id result21 = [archive2 decodeObjectForKey:@"111"];
id result22 = [archive2 decodeObjectForKey:@"222"];
NSLog(@"resut21:%@\n result22:%@",result21,result22);
注意:多個(gè)對(duì)象initForWritingWithMutableData歸檔時(shí),finishEncoding方法之后,不能在歸檔,再寫encode會(huì)報(bào)錯(cuò);所以這個(gè)和數(shù)據(jù)庫不一樣,也就不能在多個(gè)地方寫入,只能一次性寫入,如多次針對(duì)同路徑文件寫入,需要?jiǎng)?chuàng)建多次keyArchive,原來的文件內(nèi)容會(huì)被清掉,只保存最近的寫入內(nèi)容。
單個(gè)對(duì)象歸檔也是一樣,是直接清掉之前并寫入新的信息。