4 應用程序的沙盒目錄下會有三個文件夾Documents、Library(下面有Caches和Preferences目錄)、tmp。
- Documents:保存應用運行時生成的需要持久化的數據,iTunes會自動備份該目錄。
蘋果建議將程序中建立的或在程序中瀏覽到的文件數據保存在該目錄下,iTunes備份和恢復的時候會包括此目錄 - inBox文件
- Library:存儲程序的默認設置和其他狀態信息,iTunes會自動備份該目錄。
1、Library/Caches:存放緩存文件,iTunes不會備份此目錄,此目錄下文件不會在應用退出刪除。一般存放體積比較大,不是特別重要的資源。
2、Library/Preferences:保存應用的所有偏好設置,iOS的Settings(設置)應用會在該目錄中查找應用的設置信息,iTunes會自動備份該目錄。
注意:您不應該直接創建偏好設置文件,而是應該使用NSUserDefaults類來取得和設置應用程序和偏好。 - tmp:保存應用運行時所需的臨時數據,使用完畢后再將相應的文件從該目錄刪除。應用沒有運行時,系統也有可能會清除該目錄下的文件,iTunes不會同步該目錄。iPhone重啟時,該目錄下的文件會被刪除。
- .app 文件 只讀
5.1 獲取Document目錄
第一種:
NSString *docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0];
第二種:
// 第一步:獲取沙盒主路徑的地址
NSString *homePathStr = NSHomeDirectory();
NSLog(@"homePathStr ==== %@", homePathStr);
// 第二步:在沙盒主路徑后拼接Documents,拼接出來documents文件夾的路徑
NSString *documentPathStr = [homePathStr stringByAppendingPathComponent:@"Documents"];
NSLog(@"documentPathStr ===== %@", documentPathStr);
5.2 獲取Library目錄
NSString *LibraryPath =[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask, YES) lastObject];
NSString *cachesPath =[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES) lastObject];
NSString *LibraryPath =[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask, YES) lastObject];
NSString *preferPath = [LibraryPathstringByAppendingPathComponent:@"Preferences"];
5.3 通常情況下,Preferences有系統維護,所以我們很少去操作它。
獲取tmp目錄
NSString *tmpPath = NSTemporaryDirectory();
二、簡單對象的讀寫(I/O)操作
簡單對象:iOS中提供四種類型可以直接進行文件存取:NSString(字符串)、NSArray(數組)、NSDictionary(字典)、NSData(數據)(以上類型包括子類)
注意:數組(可變與不可變)和字典(可變與不可變)中元素對象的類型,也必須是上述四種,否則不能直接寫入文件
字符串對象寫入文件
//獲取Document目錄NSString *documentPathStr =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0];
//構造字符串文件的存儲路徑NSString *strPath = [documentPathStr stringByAppendingPathComponent:@"text.txt"];
//構造字符串對象NSString *foo_str = @"this is a test";
//通過將writeToFile:atomically:encoding:error:方法發送給字符串對象完成字符串存儲到文件內的功能
[foo_str writeToFile:strPath atomically:YES
encoding:NSUTF8StringEncoding error:nil];
//從文件中讀取字符串對象NSString *newStr = [NSString stringWithContentsOfFile:strPath encoding:NSUTF8StringEncoding error:nil];
**NSData寫入/讀取**
NSData對象寫入文件
**// 將UIImage類型對象轉化成NSData類型的**// 圖片名.png// 圖片名@2X.png// 圖片名@3X.pngUIImage *image = [UIImage imageNamed:@"圖片名"];
// 根據imageNamed獲取到的圖片會在緩存里面存一份,下次再獲取同名圖片,直接從緩存里面取。優點:快,只有第一次的時候稍慢,但是之后再去獲取的話會很快。缺點:會浪費內存,如果只用一次的話這塊內存就浪費掉了。// 根據ContentsOfFile獲取到的圖片每一次都會根據路徑去取圖片,不會占用內存。如果這個圖片只使用一次的話,推薦使用ContentsOfFile。NSData *data = UIImage**JPEG**Representation(image, 1);
// 第一個參數:轉哪個UIImage類型的對象// 第二個參數:壓縮系數,越小壓縮的越厲害// 將data存入到本地// 讀取出來,並放在imageView上顯示NSString *dataFile = [documentPathStr stringByAppendingPathComponent:@"123.PNG"];
[data writeToFile:dataFile atomically:YES];
**//將NSData 轉成UIImage類型**NSData *newData = [NSData dataWithContentsOfFile:dataFile];
UIImage *newImage = [[UIImage alloc] initWithData:newData];
UIImageView *imageView = [[UIImageView alloc] initWithImage:newImage];
[self.view addSubview:imageView];
//構造二進制文件的存儲路徑 NSString *dataPath = [documentPathstringByAppendingPathComponent@"data"];
//通過將writeToFile:atomically:方法發送給二進制對象完成二進制存儲到文件內的功能 [foo_data writeToFile:dataPath atomically:YES];
注:二進制對象可能存儲的是圖像、字符串等等。
從文件中讀取NSData數據 NSData *data = [NSData dataWithContentsOfFile:dataPath]; UIImage *image = [UIImage imageWithData:data];
三、文件管理器與文件對接器
文件管理器(NSFileManager):此類主要是對文件進行的操作(創建/刪除/改名等)以及文件信息的獲取。
文件連接器(NSFileHandle):此類主要是對文件內容進行讀取和寫入操作。 文件管理器:
1、創建文件管理器對象 NSFileManager = [NSFileManager defaultManager];
2、創建一個文件並寫入數據 - (BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data attributes:(NSDictionary *)dic;
3、從一個文件中讀取數據 - (NSData *)contentsAtPath:(NSString *)path;
4、srcPath路徑上的文件移動到desPath路徑上。(注意這里的路徑是文件路徑而不是目錄)- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)desPath error:(NSError *)error;
文件連接器:
1、打開一個文件准備讀取 + (id)fileHandleForReadingAtPath:(NSString*)path;
2、打開一個文件准備寫入 + (id)fileHandleForWritingAtPath:(NSString*)path;
3、打開一個文件准備更新 + (id)fileHandleForUpdatingAtPath:(NSString*)path;
4、從設備或通道返回可用的數據- (NSData *)availableData;
5、從當前的節點讀取到文件的末尾 - (NSData *)readDataToEndOfFile;
6、從當前的節點開始讀取指定的長度數據 - (NSData *)readDataOfLength:(NSUInteger)length;
7、寫入數據 -(void)writeData:(NSData*)data;
8、獲取當前文件的偏移量 - (unsigned long long)offsetInFile;
9、跳到指定文件的偏移量 - (void)seekToFileOffset:(unsigned long long)offset;
10、跳到文件末尾 - (unsigned long long)seekToEndOfFile;
11、將文件的長度設為offset字節 - (void)truncateFileAtOffset:(unsigned long long)offset;
12、關閉文件- (void)closeFile;
四、復雜對象的讀寫(I/O)操作
什么是復雜對象?
在Foundation框架內不存在的數據類,如:自定義Person類無法在程序內通過writeToFile:這個方法寫入到文件內
歸檔與反歸檔
如何將復雜對象寫入文件?
復雜對象無法通過writeToFile:方法進行數據持久化,只能通過將復雜對象轉換為NSData(這個步驟就是歸檔),然后在通過writeToFile:寫入文件
如何從文件中讀取復雜對象? 從文件中讀取NSData數據,將NSData轉換為復雜對象(這個步驟就是反歸檔)
記住:1、復雜對象寫入文件的過程(復雜對象->歸檔->NSData->writeToFile)
2、從文件中讀取出復雜對象過程(讀取文件->NSData->反歸檔->復雜對象)
如何進行歸檔與反歸檔
1、首先,復雜對象所屬的類要遵守協議(NSCoding協議)
2、其次,實現協議中的兩個方法:
①、- (void)encodeWithCoder:(NSCoder *)aCoder;//序列化
②、- (id)initWithCoder:(NSCoder *)aDecoder;//反序列化
代碼實現:
1.首先,遵守NSCoding協議
@interface Person: NSObject<NSCoding>
@property(nonatomic, copy)NSString *name;
@property(nonatomic, assign)Integer age;
@end2.其次,實現協議中的兩個方法
//對person對象進行歸檔時,此方法執行//對person中想要進行歸檔的所有屬性,進行序列化操作
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encoderObject:self.name forKey:@"name"];
[aCoder encoderInteger:self.age forKey:@"age"];
}
//對person對象進行反歸檔(解檔)時,該方法執行//創建一個新的對象person,所有屬性都是通過反序列化得到的
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if(self){
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeObjectForKey:@"age"];
}
return self;
}
//歸檔//准備一個NSMutableData,用於保存歸檔后的對象NSMutableData *data = [NSMutableData data];
//創建歸檔工具NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
//歸檔
[archiver encodeObject:p1 forKey:@"p1"];
//結束
[archiver finishEncodeing];
//拼接寫入沙盒路徑NSString *caches = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES)[0];
NSString *filePath = [caches stringByAppendingPathComponent:@"person"];
//寫入沙盒
[data writeToFile: filePath atomically:YES];
//反歸檔(解檔)//從filePath文件路徑讀取NSData *data = [NSData dataWithContentsOfFile:filePath];
//反歸檔工具NSKeyedUnarchiver *unArchiver = [[ MSKeyedUnarchiver alloc] initForReadingWithData:data];
//反歸檔成對象
Person *p2 = [unArchiver decodeObjectForKey:@"p1"];
//反歸檔結束
[unArchiver finishDecoding];