iOS數據持久化
// // AppDelegate.m // //import "AppDelegate.h"
import "Person.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
(void)dealloc { [_window release]; [super dealloc]; }
(BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible];
// 此函數可以通過制定的目錄名稱(第一個參數)和指定的作用域(第二個參數)以及 BOOL 類型的參數來確定是否返回完整路徑,該函數的返回值類型為數組。 返回值之所以是數組因為,作用域里會有若干個相同的目錄。
NSArray *filePaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// 數據持久化常用的文件夾為 Documents 。
NSLog( @"Documents:%@", filePaths.firstObject ) ;
// 數據持久化常用的文件夾:tmp。但是重要的用戶數據要存儲在 Documents 文件夾中。
NSString *tmpFilePath = NSTemporaryDirectory();
NSLog( @"tmp:%@", tmpFilePath ) ;
//應用程序在安裝完成后會在對應的沙盒中產生一個.app文件(與之對應的類為 NSBundle ),工程中的資源文件會保存在這個.app文件中,此.app文件是只讀的,我們通常叫他應用程序包。
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"beutifuly" ofType:@"jpg"];
NSLog( @"%@", imagePath ) ;
// 獲取存儲文件的 Documents 文件夾路徑
NSString *docPath = filePaths.lastObject;
// text文件路勁的生成
// NSString textFilePath = [docPath stringByAppendingString:@"/text.txt"]; NSString textFilePath = [docPath stringByAppendingPathComponent:@"text.txt"]; NSLog( @"%@", textFilePath );
// 簡單對象寫入文件
// 1、字符串寫入文本文件
NSString *str = @"字符串寫入文本文件";
[str writeToFile:textFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
// 2、數組寫入
NSString *arrayPath = [docPath stringByAppendingPathComponent:@"array.plist"];
NSLog( @"%@", arrayPath );
NSArray *array = @[@"哈哈", @"呵呵", @"嘿嘿", @123];
[array writeToFile:arrayPath atomically:YES];
// 3、字典寫入文件
NSString *dictPath = [docPath stringByAppendingPathComponent:@"dict.plist"];
NSDictionary *dict = @{@"姓名":@"wang", @"性別":@"zhen", @"年齡":@12};
[dict writeToFile:dictPath atomically:YES];
// 4、NSData 寫入文件(可以寫入文本字符串,音頻,視頻,圖片等等)
NSString *dataPath = [docPath stringByAppendingPathComponent:@"soYBAFVSEQ2IVhkZAA6sj5uH4wQAAAVIgLO86QADqyn976.m4a"];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://fs.open.kugou.com/3a25cd93b65ac6611a2503dd8ad67976/55536711/G018/M08/0A/17/soYBAFVSEQ2IVhkZAA6sj5uH4wQAAAVIgLO86QADqyn976.m4a"]];
[imageData writeToFile:dataPath atomically:YES];
NSLog( @"%@", dataPath );
// 使用 NSFileManager 來管理文件
// 1、創建文件夾
NSFileManager *filManager = [NSFileManager defaultManager];
[filManager createDirectoryAtPath:[docPath stringByAppendingPathComponent:@"xxx"] withIntermediateDirectories:YES attributes:nil error:nil];
// 應該先判斷對應路勁的文件是否存在,如果存在,先讀取文件內容,然后拼接新內容,再寫入到文件中。
NSString *contentStr = nil;
// 通過文件管理對象判斷指定文件路勁的文件是否存在
if ([filManager fileExistsAtPath:textFilePath]) {
contentStr = [NSString stringWithContentsOfFile:textFilePath encoding:NSUTF8StringEncoding error:nil];
}
else {
contentStr = [NSString string];
}
// 拼接新的字符串
contentStr = [contentStr stringByAppendingString:@"\n哈哈哈哈哈哈哈"];
// 再將拼接完的字符串重新寫入到文件中(這種方法太占內存,應該使用文件指針 NSFileHanle, 操作文件)
[contentStr writeToFile:textFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
// 復雜對象寫入文件(歸檔和反歸檔)
NSMutableArray *personList = [NSMutableArray array];
for (int i = 0; i < 100; i++) {
Person *aPerson = [[[Person alloc] init] autorelease];
aPerson.name = @"wang";
aPerson.gender = @"男";
aPerson.age = 123;
[personList addObject:aPerson];
}
// 指定文件路徑
NSString *arcPath = [docPath stringByAppendingPathComponent:@"person.arc"];
// 使用歸檔對象,歸檔對應的數據
[NSKeyedArchiver archiveRootObject:personList toFile:arcPath];
// 使用反歸檔類,獲取已歸檔的數據
// Person person = [NSKeyedUnarchiver unarchiveObjectWithFile:arcPath]; // NSLog( @"%@, %@, %ld", person.name, person.gender, person.age ) ; NSArray person = [NSKeyedUnarchiver unarchiveObjectWithFile:arcPath];
NSLog( @"%@", person ) ;
// 返回當前應用程序的所在的主目錄,即沙箱目錄。
NSString *homePath = NSHomeDirectory();
NSLog( @"%@", homePath ) ;
return YES;
}
(void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. }
(void)applicationDidEnterBackground:(UIApplication *)application { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. }
(void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. }
(void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. }
(void)applicationWillTerminate:(UIApplication *)application { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. }
@end</pre>
// // Person.h // //import <Foundation/Foundation.h>
@interface Person : NSObject<NSCoding> /// 如果一個自定義類的對象要支持歸檔,則需要遵守 NSCoding 協議,并實現編碼和解碼協議方法。
@property (nonatomic, retain) NSString name ; @property (nonatomic, retain) NSString gender ; @property (nonatomic, assign) NSInteger age ;
@end // Person</pre>
// // Person.m // //import "Person.h"
@implementation Person
// 編碼協議是讓當前類的對象通過固定的編碼規則轉成 NSData 類型的數據
- (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:self.name forKey:@"NAME"]; [aCoder encodeObject:self.gender forKey:@"GENDER"]; [aCoder encodeInteger:self.age forKey:@"AGE"]; }
// 解碼方法,是在反歸檔的時候將NSData類型的數據轉成當前類的對象時調用的。解碼時用到的key要跟編碼時指定的key保持一致。
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
} return self; }self.name = [aDecoder decodeObjectForKey:@"NAME"]; self.gender = [aDecoder decodeObjectForKey:@"GENDER"]; self.age = [aDecoder decodeIntegerForKey:@"AGE"];
@end</pre>