數據處理之文件讀寫

數據持久化的方式
1.屬性列表property.plist
2.NSUserDefaults(偏好設置)
3.write to file(寫入文件)
4.sqlite(iOS中的輕量級數據庫)
5.CoreData(蘋果基于sqlite封裝的數據管理方式)

可視化的源碼都是xml
documents:用來保存應用程序運行需要的持久化數據,通常是用戶固定需要的數據,iTunes在自動備份時會自動備份此文件夾。

// 參數
// 1.主路徑名稱
// 2.當前用戶(iOS端默認使用NSUserDomainMask)
// 3.是否使用絕對路徑
// YES絕對路徑-NO相對路徑~(Domain領域,區域)
NSString *documentPath = [NSSearchPathForDirectoriesInDomains( 
                                           NSDocumentDirectory, 
                                           NSUserDomainMask, 
                                           YES) objectAtIndex:0];

library:通常用來存儲當前應用程序運行期間需要的一些內存,包括緩存和偏好設置。

 NSString *libraryPath = NSSearchPathForDirectoriesInDomains(
                                           NSLibraryDirectory, 
                                           NSUserDomainMask, 
                                           YES)[0];   

caches:用來存放緩存文件,但是iTunes并不會備份此文件夾。

NSString *cachePath = [NSSearchPathForDirectoriesInDomains(
                                           NSCachesDirectory, 
                                           NSUserDomainMask,
                                           YES)firstObject];

preferences:用來存儲應用的偏好設置,iTunes會自動備份此文件夾。

但是此文件夾不能被直接被尋找到,需要路徑拼接,因為我們一般不會直接操作保存用戶的偏好設置的內容,而是通過操作來使對應的代碼生效,然后存儲到這個文件夾。比如NSUserDefaults

NSString *preferencesPath = [NSSearchPathForDirectoriesInDomains(
                                           NSPreferencePanesDirectory, 
                                           NSUserDomainMask, 
                                           YES)firstObject];
NSLog(@"%@",preferencesPath);// 能打印出來但是沒有此地址的數據

NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[ud setObject:@"游客" forKey:@"use_id"];
[ud setBool:YES forKey:@"NightModel"];
[ud setInteger:11 forKey:@"time"];

tmp:用來存放臨時文件的文件夾。程序運行期間有可能里面的文件會時不時消失掉,所以永遠不要使用此文件夾來存儲需要持久化得數據。iTunes不會備份此文件夾。

NSString *tmpPath = NSTemporaryDirectory();

包文件

// 路徑
NSString *bundlePath = [[NSBundle mainBundle]resourcePath];
NSLog( @"%@",bundlePath);
// 獲取包內文件
NSString *imagePath = [[NSBundle mainBundle]pathForResource:@"12" ofType:@"jpg"];
UIImage *image =  [UIImage imageWithContentsOfFile:imagePath];

簡單對象寫入文件

1.字符串寫入文件
NSString *incantation = @"I love my iOS teacher!";

NSString *path = [NSSearchPathForDirectoriesInDomains(
                                  NSDocumentDirectory,
                                  NSUserDomainMask, 
                                  YES)lastObject];
//path = [path stringByAppendingString:@"/a.txt"];//拼接地址文件

//path = [path stringByAppendingPathComponent:@"b.txt"];

path = [path stringByAppendingPathComponent:@"許晟馗@郝文舉.avi"];
//寫入文件
// 參數
// 1.路徑,傳入一個文件寫入的地方,并且提供文件名稱
// 2.YES為安全保護,在文件寫入時如果中斷了操作,那么操作恢復時可以保證文件的完整性。NO,不作任何保護。
// 3.數據寫入文件的編碼方式。
// 4.錯誤對象。
NSError *error = nil;
[incantation writeToFile:path 
              atomically:YES 
                encoding:NSUTF8StringEncoding 
                   error:&error];  
// 從文件中讀取
NSString *result = [NSString stringWithContentsOfFile:path 
                                             encoding:NSUTF8StringEncoding
                                                error:nil];
NSLog(@"%@",result);
全局屬性NSString *docPath;
self.docPath = [NSSearchPathForDirectoriesInDomains(
                                 NSDocumentDirectory, 
                                 NSUserDomainMask,
                                 YES)lastObject];  
2.數組寫入文件
// 準備數組
NSArray *array = @[@1,@2,@3,@4];
// 準備即將寫入的路徑
NSString *path0 = [self.docPath stringByAppendingPathComponent:@"array"];
// 將數組寫入路徑
[array writeToFile:path0 atomically:YES];
// 根據路徑讀取數組
NSArray *resultArray = [NSArray arrayWithContentsOfFile:path0];
// 打印驗證結果
NSLog(@"%@",resultArray);
3.字典寫入
NSDictionary *dict = @{@"1":@"q",@"2":@"w",@"3":@"e"};

NSString *path1 = [self.docPath stringByAppendingPathComponent:@"dict"];

[dict writeToFile:path1 atomically:YES];

NSDictionary *resultDict = [NSDictionary dictionaryWithContentsOfFile:path1];

NSLog(@"%@",resultDict);
4.復雜對象寫入文件
// 二進制流文件寫入文件

UIImage *image0 = [UIImage imageNamed:@"12.jpg"];
// 使用JPEG的渲染方式將圖片轉化為二進制流
// 第一個參數為需要轉化的圖片,第二個為壓縮比例,范圍為0~1
// UIImagePNGRepresentation(UIImage * _Nonnull image)

NSData *data = UIImageJPEGRepresentation(image0, 1);

NSString *path2 = [self.docPath stringByAppendingPathComponent:@"aaa.jpg"];

[data writeToFile:path2 atomically:YES];
// 從文件中獲取圖片
UIImage *resultImage = [UIImage imageWithContentsOfFile:path2];
真正的深拷貝只有歸檔和反歸檔
SingleVip * s1 = [SingleVip new];
s1.name = @"張河山";
s1.age = 20;
s1.gender = @"male";

// 歸檔(將復雜對象轉化為NSData的方式)

// 創建可變的二進制流用來存放即將轉化的model數據
NSMutableData *mutdata = [NSMutableData new];
// 創建歸檔管理器,并制定要使用的可變二進制流控制器
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:mutdata];
// 歸檔操作(key值用于標記,方便飯歸檔時提取內容)
[archiver encodeObject:s1 forKey:@"s11"];
// 結束歸當操作
[archiver finishEncoding];
// 寫入文件
NSString *path6 = [self.docPath stringByAppendingPathComponent:@"s1"];
[mutdata writeToFile:path atomically:YES];

// 反歸檔

// 從文件中獲取NSData數據
NSData *data0 = [NSData dataWithContentsOfFile:path6];
// 創建反歸檔管理器,并制定要獲取的data數據來源
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc ]initForReadingWithData:data0];
// 反歸檔操作(根據歸檔時標記的key只操作)
SingleVip *s2 = [unarchiver decodeObjectForKey:@"s11"];
// 結束反歸檔
[unarchiver finishDecoding];
NSLog(@"%@-+-%@",s1,s2);
淺拷貝地址一樣,就是兩個指針指向同一地區,深拷貝地址不一樣,是因為重新開辟地區放入相同事物
SingleVip * s1 = [SingleVip new];
SingleVip * s2 = [SingleVip new];

/*
  沒有真正意義上的深拷貝,除了歸檔和反歸檔,
  因為可變數組的深拷貝雖然數組指針地址不同
  但是里面同一個元素(model)的地址還是一樣。
*/
// 淺拷貝(不可變變不可變)
NSArray *array = @[s1,s2];
NSArray *_array = [array copy];
NSLog(@"%p-%p",array,_array);

// 深拷貝(不可變變可變)
NSArray *array1 = @[s1,s2];
NSMutableArray *mutArray = [array mutableCopy];
NSLog(@"%p-%p",array1,mutArray);
// 深拷貝(可變變不可變)
NSMutableArray *mutArray2 = [NSMutableArray arrayWithObjects:s1,s2, nil];
NSArray *array2 = [mutArray copy];// copy出的都是不可變的
NSLog(@"%p-%p",array2,mutArray2);
// 深拷貝(可變變可變)
NSMutableArray *mutArray3 = [mutArray2 mutableCopy];
NSLog(@"%p-%p",mutArray2,mutArray3);
    
SingleVip *s3 = [s1 copy];
NSLog(@"%p-%p",s1,s3);
SingleVip *s4 = [s1 mutableCopy];
NSLog(@"%p-%p",s1,s4);
點擊方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    // 因為是單例,所以在程序的任何地方都可以獲取
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
   // 可以獲取存儲在屬性列表里面的值,然后作相應的操作
    if ([[ud objectForKey:@"use_id"] isEqualToString:@"游客"]) {
   
       NSLog(@"尊敬的用戶請您登陸!");
    }
}

自定義的model類創建的復雜對象,無法響應writeToFile消息,不能直接寫入文件。所以想要完成轉化,需遵循NSCoding協議,實現兩個編碼方法。
在歸檔過程中,需要自定義實現歸檔的細節,將簡單對象使用key值標記完成歸檔記錄
在反歸檔過程中,同樣需要根據歸檔記錄時的標記來解碼,完成屬性值的對應

.h

#import <Foundation/Foundation.h>

@interface SingleVip : NSObject<NSCoding,NSCopying,NSMutableCopying>

@property(strong,nonatomic,nonnull)NSString  *name;
@property(assign,nonatomic)NSInteger  age;
@property(strong,nonatomic,nullable)NSString  *gender;

@end        

.m

#import "SingleVip.h"

@implementation SingleVip

// 歸檔(編碼)
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    // 逐條
    [aCoder encodeObject:_name forKey:@"name"];
    [aCoder encodeInteger:_age forKey:@"age"];
    [aCoder encodeObject:_gender forKey:@"gender"];
}
// 反歸檔(解碼)
- (instancetype)initWithCoder:(NSCoder *)aDecoder{

    if (self = [super init]) {
        _name = [aDecoder decodeObjectForKey:@"name"];
        _age = [aDecoder decodeIntegerForKey:@"age"];
        _gender = [aDecoder decodeObjectForKey:@"gender"];
    }

    return self;
}
// 要實現深淺拷貝,首先要遵循NSCopying協議,然后寫一下方法->copyWithZone
/*
- (id)copyWithZone:(NSZone *)zone{
// 淺拷貝直接返回self
    return self;
}

- (id)mutableCopyWithZone:(NSZone *)zone{

    return self;
}
*/
- (id)copyWithZone:(NSZone *)zone{
    // 深拷貝
    id obj = [[[self class] allocWithZone:zone] init];

    return obj;
}

- (id)mutableCopyWithZone:(NSZone *)zone{

    // 深拷貝
    id obj = [[[self class] allocWithZone:zone] init];

    return obj;

}

@end  
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容