IOS四種保存文件的方式

在iOS開發(fā)過程中,不管是做什么應(yīng)用廉羔,都會碰到數(shù)據(jù)保存的問題。將數(shù)據(jù)保存到本地僻造,能夠讓程序的運行更加流暢憋他,不會出現(xiàn)讓人厭惡的菊花形狀,使得用戶體驗更好髓削。下面介紹一下數(shù)據(jù)保存的方式:

1.NSKeyedArchiver:采用歸檔的形式來保存數(shù)據(jù)竹挡,該數(shù)據(jù)對象需要遵守NSCoding協(xié)議,并且該對象對應(yīng)的類必須提供encodeWithCoder:和initWithCoder:方法立膛。前一個方法告訴系統(tǒng)怎么對對象進行編碼揪罕,而后一個方法則是告訴系統(tǒng)怎么對對象進行解碼梯码。例如對Possession對象歸檔保存。

定義Possession:

@interface Possession:NSObject{//遵守NSCoding協(xié)議

NSString *name;//待歸檔類型

}

@implementation Possession

-(void)encodeWithCoder:(NSCoder *)aCoder{

[aCoder encodeObject:name forKey:@"name"];

}

-(void)initWithCoder:(NSCoder *)aDecoder{

name=[[aDeCoder decodeObjectforKey:@"name"] retain];

}

歸檔操作:

如果對Possession對象allPossession歸檔保存好啰,只需要NSCoder子類NSKeyedArchiver的方法archiveRootObject:toFile: 即可轩娶。

NSString *path = [self possessionArchivePath];

[NSKeyedArchiver archiveRootObject:allPossessions toFile: path ]

解壓操作:

同樣調(diào)用NSCoder子類NSKeyedArchiver的方法unarchiveRootObject:toFile: 即可

allPossessions = [[NSKeyedUnarchiver unarchiveObjectWithFile:path] retain];

缺點:歸檔的形式來保存數(shù)據(jù),只能一次性歸檔保存以及一次性解壓框往。所以只能針對小量數(shù)據(jù)鳄抒,而且對數(shù)據(jù)操作比較笨拙,即如果想改動數(shù)據(jù)的某一小部分椰弊,還是需要解壓整個數(shù)據(jù)或者歸檔整個數(shù)據(jù)许溅。

2.NSUserDefaults:用來保存應(yīng)用程序設(shè)置和屬性、用戶保存的數(shù)據(jù)秉版。用戶再次打開程序或開機后這些數(shù)據(jù)仍然存在贤重。NSUserDefaults可以存儲的數(shù)據(jù)類型包括:NSData、NSString清焕、NSNumber并蝗、NSDate、NSArray耐朴、NSDictionary借卧。如果要存儲其他類型,則需要轉(zhuǎn)換為前面的類型筛峭,才能用NSUserDefaults存儲铐刘。具體實現(xiàn)為:

保存數(shù)據(jù):

NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];

NSString *name =@”default string“;

[defaults setObject:firstName forKey:@"name"];

//獲得UIImage實例

UIImage *image=[[UIImage alloc]initWithContentsOfFile:@"photo.jpg"];

NSData *imageData = UIImageJPEGRepresentation(image, 100);//UIImage對象轉(zhuǎn)換成NSData

[defaults synchronize];//用synchronize方法把數(shù)據(jù)持久化到standardUserDefaults數(shù)據(jù)庫

讀取數(shù)據(jù)

NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];

NSString *name = [defaults objectForKey:@"name"];//根據(jù)鍵值取出name

NSData *imageData = [defaults dataForKey:@"image"];

UIImage *Image = [UIImage imageWithData:imageData];//NSData轉(zhuǎn)換為UIImage

3. Write寫入方式:永久保存在磁盤中。具體方法為:

第一步:獲得文件即將保存的路徑:

NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,? NSUserDomainMask,YES);//使用C函數(shù)NSSearchPathForDirectoriesInDomains來獲得沙盒中目錄的全路徑影晓。該函數(shù)有三個參數(shù)镰吵,目錄類型、he domain mask挂签、布爾值疤祭。其中布爾值表示是否需要通過~擴展路徑。而且第一個參數(shù)是不變的饵婆,即為NSSearchPathDirectory 勺馆。在IOS中后兩個參數(shù)也是不變的,即為:NSUserDomainMask 和 YES侨核。

NSString *ourDocumentPath =[documentPaths objectAtIndex:0];

還有一種方法是使用NSHomeDirectory函數(shù)獲得sandbox的路徑哄孤。具體的用法為:

NSString *sandboxPath = NSHomeDirectory();

// Once you have the full sandbox path, you can create a path from it犬缨,但是不能在sandbox的本文件層上寫文件也不能創(chuàng)建目錄儒搭,而應(yīng)該是此基礎(chǔ)上創(chuàng)建一個新的可寫的目錄捧请,例如Documents,Library或者temp。

NSString *documentPath = [sandboxPath

stringByAppendingPathComponent:@"Documents"];//將Documents添加到sandbox路徑上些己,具體原因前面分析了豌鸡!

這兩者的區(qū)別就是:使用NSSearchPathForDirectoriesInDomains比在NSHomeDirectory后面添加Document更加安全嘿般。因為該文件目錄可能在未來發(fā)送的系統(tǒng)上發(fā)生改變。

第二步:生成在該路徑下的文件:

NSString *FileName=[documentDirectory stringByAppendingPathComponent:fileName];//fileName就是保存文件的文件名

第三步:往文件中寫入數(shù)據(jù):

[data writeToFile:FileName atomically:YES];//將NSData類型對象data寫入文件涯冠,文件名為FileName

最后:從文件中讀出數(shù)據(jù):

NSData data=[NSData dataWithContentsOfFile:FileName options:0 error:NULL];//從FileName中讀取出數(shù)據(jù)

4. SQLite:采用SQLite數(shù)據(jù)庫來存儲數(shù)據(jù)炉奴。SQLite作為一中小型數(shù)據(jù)庫,應(yīng)用ios中功偿,跟前三種保存方式相比盆佣,相對比較復(fù)雜一些往堡。還是一步步來吧械荷!

第一步:需要添加SQLite相關(guān)的庫以及頭文件:在項目文件的Build Phases下,找到Link Binary Library(ies)虑灰,添加libsqlite3.0.dylib(libsqlite3.dylib與前者的區(qū)別暫時不知吨瞎,兩者應(yīng)該差不多);在項目文件中頭文件或者源文件中添加頭文件#import "/usr/include/sqlite3.h"

第二步:開始使用SQLite:

NSArray *documentsPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask , YES);

NSString *databaseFilePath=[[documentsPaths objectAtIndex:0] stringByAppendingPathComponent:@"mydb"];

//上面兩句已經(jīng)比較熟悉了吧穆咐!

//打開數(shù)據(jù)庫

if (sqlite3_open([databaseFilePath UTF8String], &database)==SQLITE_OK) {

NSLog(@"sqlite dadabase is opened.");

}

else{ return;}//打開不成功就返回

在打開了數(shù)據(jù)庫的前提下颤诀,如果數(shù)據(jù)庫沒有表,那就開始建表了哦对湃!

char *error;

const char *createSql="create table(id integer primary key autoincrement, name text)";

if (sqlite3_exec(database, createSql, NULL, NULL, &error)==SQLITE_OK) {

NSLog(@"create table is ok.");

}

else

{

NSLog(@"error: %s",error);

sqlite3_free(error);//每次使用完畢清空error字符串崖叫,提供給下一次使用

}

建表完成之后,就開始插入記錄:

const char *insertSql="insert into a person (name) values(‘gg’)";

if (sqlite3_exec(database, insertSql, NULL, NULL, &error)==SQLITE_OK) {

NSLog(@"insert operation is ok.");

}

else

{

NSLog(@"error: %s",error);

sqlite3_free(error);//每次使用完畢清空error字符串拍柒,提供給下一次使用

}

下一步心傀,查詢記錄:

const char *selectSql="select id,name from a person";

sqlite3_stmt *statement;

if (sqlite3_prepare_v2(database,selectSql, -1, &statement, nil)==SQLITE_OK) {

NSLog(@"select operation is ok.");

}

else

{

NSLog(@"error: %s",error);

sqlite3_free(error);

}

while(sqlite3_step(statement)==SQLITE_ROW) {

int _id=sqlite3_column_int(statement, 0);

NSString *name=(char*)sqlite3_column_text(statement, 1);

NSLog(@"row>>id %i, name %s",_id,name);

}

sqlite3_finalize(statement);

最后,關(guān)閉數(shù)據(jù)庫:

sqlite3_close(database);

注意:寫入數(shù)據(jù)庫拆讯,字符串可以采用char方式脂男,而從數(shù)據(jù)庫中取出char類型,當char類型有表示中文字符時种呐,會出現(xiàn)亂碼宰翅。這是因為數(shù)據(jù)庫默認使用ascII編碼方式。所以要想正確從數(shù)據(jù)庫中取出中文爽室,需要用NSString來接收從數(shù)據(jù)庫取出的字符串汁讼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市阔墩,隨后出現(xiàn)的幾起案子嘿架,更是在濱河造成了極大的恐慌,老刑警劉巖戈擒,帶你破解...
    沈念sama閱讀 222,946評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件眶明,死亡現(xiàn)場離奇詭異,居然都是意外死亡筐高,警方通過查閱死者的電腦和手機搜囱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評論 3 399
  • 文/潘曉璐 我一進店門丑瞧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蜀肘,你說我怎么就攤上這事绊汹。” “怎么了扮宠?”我有些...
    開封第一講書人閱讀 169,716評論 0 364
  • 文/不壞的土叔 我叫張陵西乖,是天一觀的道長。 經(jīng)常有香客問我坛增,道長获雕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,222評論 1 300
  • 正文 為了忘掉前任收捣,我火速辦了婚禮届案,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘罢艾。我一直安慰自己楣颠,他們只是感情好,可當我...
    茶點故事閱讀 69,223評論 6 398
  • 文/花漫 我一把揭開白布咐蚯。 她就那樣靜靜地躺著童漩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪春锋。 梳的紋絲不亂的頭發(fā)上矫膨,一...
    開封第一講書人閱讀 52,807評論 1 314
  • 那天,我揣著相機與錄音看疙,去河邊找鬼豆拨。 笑死,一個胖子當著我的面吹牛能庆,可吹牛的內(nèi)容都是我干的施禾。 我是一名探鬼主播,決...
    沈念sama閱讀 41,235評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼搁胆,長吁一口氣:“原來是場噩夢啊……” “哼弥搞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起渠旁,我...
    開封第一講書人閱讀 40,189評論 0 277
  • 序言:老撾萬榮一對情侶失蹤攀例,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后顾腊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體粤铭,經(jīng)...
    沈念sama閱讀 46,712評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,775評論 3 343
  • 正文 我和宋清朗相戀三年杂靶,在試婚紗的時候發(fā)現(xiàn)自己被綠了梆惯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酱鸭。...
    茶點故事閱讀 40,926評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖垛吗,靈堂內(nèi)的尸體忽然破棺而出凹髓,到底是詐尸還是另有隱情,我是刑警寧澤怯屉,帶...
    沈念sama閱讀 36,580評論 5 351
  • 正文 年R本政府宣布蔚舀,位于F島的核電站,受9級特大地震影響锨络,放射性物質(zhì)發(fā)生泄漏赌躺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,259評論 3 336
  • 文/蒙蒙 一足删、第九天 我趴在偏房一處隱蔽的房頂上張望寿谴。 院中可真熱鬧锁右,春花似錦失受、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至码泞,卻和暖如春兄旬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背余寥。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評論 1 274
  • 我被黑心中介騙來泰國打工领铐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宋舷。 一個月前我還...
    沈念sama閱讀 49,368評論 3 379
  • 正文 我出身青樓绪撵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親祝蝠。 傳聞我的和親對象是個殘疾皇子音诈,可洞房花燭夜當晚...
    茶點故事閱讀 45,930評論 2 361

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

  • 沙盒 Plist Preference偏好設(shè)置 NSKeyedArchiver歸檔 / NSKeyedUnarch...
    追風者366閱讀 3,358評論 0 6
  • 概論 所謂的持久化,就是將數(shù)據(jù)保存到硬盤中绎狭,使得在應(yīng)用程序或機器重啟后可以繼續(xù)訪問之前保存的數(shù)據(jù)细溅。在iOS開發(fā)中,...
    Leeson1989閱讀 1,918評論 4 1
  • 在iOS開發(fā)過程中儡嘶,不管是做什么應(yīng)用喇聊,都會碰到數(shù)據(jù)保存的問題。將數(shù)據(jù)保存到本地蹦狂,能夠讓程序的運行更加流暢誓篱,不會出現(xiàn)...
    我覺得ok_閱讀 721評論 0 0
  • 在iOS開發(fā)過程中邻耕,不管是做什么應(yīng)用,都會碰到數(shù)據(jù)保存的問題燕鸽。將數(shù)據(jù)保存到本地兄世,能夠讓程序的運行更加流暢,不會出現(xiàn)...
    weigegege閱讀 447評論 0 0
  • 在iOS開發(fā)過程中啊研,不管是做什么應(yīng)用御滩,都會碰到數(shù)據(jù)保存的問題。將數(shù)據(jù)保存到本地党远,能夠讓程序的運行更加流暢削解,不會出現(xiàn)...
    HZX大雄閱讀 335評論 0 0