iOS進階(一)數據處理之文件讀寫

一、沙盒機制

沙盒機制

  • 每一個應用程序都會擁有一個應用程序沙盒
  • 應用程序沙盒就是一個文件系統目錄

iOS中的沙盒機制

  • 沙盒是一種安全體系
  • TA規定了應用程序只能在為該程序創建的文件夾(沙盒)內訪問文件,不可以訪問其他沙盒內的內容(iOS8已經部分開放訪問)
  • 所有的非代碼文件都保存在這個地方,比如圖片、音樂、屬性列表(plist)、sqlite數據庫和文本文件等

沙盒機制的特點

  • 每個應用程序的活動范圍都限定在自己的沙盒里面
  • 不能隨意跨越自己的沙盒去訪問別的應用程序沙盒中的內容(iOS已經部分開放訪問)
  • 應用程序向外請求或接受數據都需要經過權限認證

前往沙盒路徑方法

  • 選中要前往的路徑,右鍵
  • 選中Services選項
  • 點擊Reveal in Finder


    前往沙盒路徑.png

沙盒中的文件夾

  • Documents:保存應用運行時生成的需要持久化的數據,iTunes會自動備份該目錄
  • Library:存儲程序的默認設置和其他狀態信息,iTunes會自動備份該目錄。
  • Library/Caches:存放緩存文件,iTunes不會備份此目錄,次目錄下文件不會在應用退出刪除。
  • Library/Preferences:保存應用的所有偏好設置,iOS的Settings(設置)應用會在該目錄中查找應用的設置信息,iTunes會自動備份該目錄。注意:你不會直接創建偏好設置文件,二十應該使用NSUserDefaults類來獲得和設置應用程序的偏好
  • tmp:保存應用運行時所需的臨時數據,使用完畢后再將相應的文件從該目錄刪除。應用沒有運行時,系統也有可能會清楚該目錄下的文件,iTunes不會同步該目錄。iphone重啟時,該目錄下的文件會被刪除

獲取Documents目錄

 NSString *path = [[NSString NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];

獲取tmp目錄

NSString *tmpPath  = NSTemporaryDirectory();

獲取Library目錄

NSString *libPath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject];

獲取Library/Caches目錄

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

獲取Library/Preferences目錄

NSString *libPath = [[NSSeachForPathDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject];
NSString *prePath = [libPath stringByAppendingPathComponent:@"Preferences"];

應用程序包所在位置

NSString *path = [NSBundle mainBundle].resourcePth;

二、簡單對象的讀寫(I/O)操作

iOS中提供4種類型可以直接進行文件存取
NSString、NSArray、NSDictionary、NSData


以上類型包含子類

字符串寫入沙盒

// 在Documents下面創建一個文本路徑,假設文本名稱為bada.txt
NSString *txtPath = [docPath stringByAppendingPathComponent:@"bada.txt"];// 此時僅存在路徑,文件并沒有真實存在
NSString *string = @"中二洪荒巴達之力";
[string writeToFile:txtPath atomically:YES encoding:NSUTF8StringEncoding error:nil];// 字符串寫入時執行的代碼
NSLog(@"%@", txtPath);

從文件中讀取字符串的方法

NSString *resultString = [NSString stringWithContentsOfFile:txtPath encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@", resultString);

數組寫入文件

// 創建一個存儲數組的文件路徑
NSString *filePath = [docPath stringByAppendingPathComponent:@"girl.txt"];
NSArray *arr = @[@"媽", @"的", @"智", @"障"];
[arr writeToFile:filePath atomically:YES];
NSLog(@"%@", filePath);

從文件中讀取數組的方法

NSArray *resultArr = [NSArray arrayWithContentsOfFile:filePath];
NSLog(@"%@", resultArr);

字典寫入文件

NSString *dicPath = [docPath stringByAppendingString:@"dic.txt"];
NSDictionary *dic = @{@"你" : @"智障", @"我" : @"機智"};
[dic writeToFile:dicPath atomically:YES];
NSLog(@"%@", dicPath);

從文件中讀取字典

NSDictionary *resultDic = [NSDictionary dictionaryWithContentsOfFile:dicPath];
NSLog(@"%@", resultDic);

NSData寫入文件

NSString *dataPath = [docPath stringByAppendingPathComponent:@"icon"];
// 得到一個UIImage對象
UIImage *image = [UIImage imageNamed:@"icon.jpg"];
// 將UIImage對象轉換成NSData對象
NSData *data = UIImageJPEGRepresentation(image, 1.0);
[data writeToFile:dataPath atomically:YES];
NSLog(@"%@", dataPath);

從文件中讀取NSData文件

NSData *resultData = [NSData dataWithContentsOfFile:dataPath];
// 將得到的NSData數據轉換為原有的圖片對象
UIImage *resultImage = [UIImage imageWithData:resultData];
// 顯示圖片
UIImageView *imageView = [[UIImageView alloc ] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
imageView.image = resultImage;
[self.view addSubview:imageView];

以上的運行結果都可以從沙盒路徑中的文件夾中看到

三、文件管理器與文件對接器

  • 文件管理器(NSFileManager):此類主要是對文件進行的操作(創建/從刪除/改名等)以及文件信息的獲取
  • 文件連接器(NSFileHandle):此類主要是對內容進行讀取和寫入操作

文件管理器的使用

創建文件夾

- (IBAction)createDirectory:(UIButton *)sender
{
    // 1.找到Caches的路徑
    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
    // 2.獲取創建的文件夾的路徑
    NSString *directoryPath = [cachePath stringByAppendingPathComponent:@"downloadImages"];
    // 3.創建文件夾需要一個文件管理對象(單例)
    NSFileManager *fileManager = [NSFileManager defaultManager];
    // 4.創建文件夾
    [fileManager createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:nil];
    
    NSLog(@"%@", directoryPath);
}

創建文件以及獲取文件信息

- (IBAction)createFile:(UIButton *)sender
{
    // 1.得到Documents的路徑
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    // 2.創建一個文件路徑
    NSString *filePath = [docPath stringByAppendingPathComponent:@"qiuxiang.txt"];
    // 3.創建文件首先需要一個文件管理對象
    NSFileManager *fileManager = [NSFileManager defaultManager];
    // 4.創建文件
    [fileManager createFileAtPath:filePath contents:[@"badaas;ldkjf;alskdjf;akjdsf;lakjsdflakjsd;flkajsdlfkjasdlfkjasldfkja;lsdfkjasldkjf;asldkfj;asfjas;ldkfjasldkfjasldkfja;lsdkfjasl;dkjfs;ladkfja;sdkfjalsdkfjalsdfkja;sdfkja;dfkja;slfkdjsalkfja;slfkja;slkdfj" dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];
    
    NSLog(@"%@", filePath);
    
    // 獲取默認文件或者某個文件夾的大小
    NSDictionary *dic = [fileManager attributesOfItemAtPath:filePath error:nil];
    NSLog(@"%@", dic);
    NSNumber *number = [dic objectForKey:NSFileSize];
    NSLog(@"%@", number);
}

文件移動

/**
    在Documents文件夾下,創建一個文件夾(path),在該文件夾下創建一個文件(test.txt),將一個圖片對象存入到該文件中,然后在Caches文件夾下創建一個文件夾名為"testDirectroy",將test.txt文件移動到這個文件夾下.
 */


// 創建文件夾
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *dirPath = [docPath stringByAppendingPathComponent:@"path"];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:nil];

// 創建文件
NSString *filePath = [dirPath stringByAppendingPathComponent:@"test.txt"];
[fileManager createFileAtPath:filePath contents:nil attributes:nil];

// 將圖片對象存入到該文件中
UIImage *image = [UIImage imageNamed:@"icon.jpg"];
NSData *data = UIImageJPEGRepresentation(image, 1.0);
[data writeToFile:filePath atomically:YES];
NSLog(@"%@", filePath);

// 移動文件
NSString *desPath = [docPath stringByAppendingPathComponent:@"test.txt"];
[fileManager moveItemAtPath:filePath toPath:desPath error:nil];

文件對接器的使用

/**
     練習要求:從一個文件中指定的位置開始追加內容
     提示:
     1、在documents目錄下創建一個test.txt文件,文件中的內容為"abcdefg"
     2、從文件偏移量為3那個位置開始追加內容"1234"
 */

- (void)change
{
    // 1.獲取Documents路徑
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    // 2.創建文件路徑
    NSString *filePath = [docPath stringByAppendingPathComponent:@"text.txt"];
    // 3.使用文件管理對象創建文件
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager createFileAtPath:filePath contents:[@"abcdefg" dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];
    // 4.創建文件對接對象
    NSFileHandle *handle = [NSFileHandle fileHandleForUpdatingAtPath:filePath];// 文件對象此時針對文件,可讀可寫
    // 5.將偏移量移動到3的位置
    [handle seekToFileOffset:3];
    // 6.寫入數據
    [handle writeData:[@"1234" dataUsingEncoding:NSUTF8StringEncoding]];
    // 7.執行完操作后,關閉文件
    [handle closeFile];
    
    NSLog(@"%@", filePath);
}

PS:這個題目有點坑爹,說是追加,其實是把defg替換成1234.

四、復雜對象的讀寫(I/O)操作

復雜對象:在Foundation框架內不存在的數據類,如自定義的Person類無法在程序內通過writeToFile:這個方法寫入到文件內

  • 如何將復雜對象寫入文件
  • 歸檔:只能通過將復雜對象轉換為NSData,然后寫入文件。
  • 如何從文件中讀取復雜對象
  • 反歸檔(又稱解檔):將NSData轉換為復雜對象

①.復雜對象寫入文件的過程:復雜對象->歸檔->NSData->writeToFile
②.從文件中讀取出復雜對象過程:讀取文件->NSData->反歸檔->復雜對象

歸檔與反歸檔

首先,復雜對象所屬的類要遵守<NSCoding>協議

@interface Person : NSObject <NSCoding>

@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *age;
@property (copy, nonatomic) NSString *gender;

- (instancetype)initWithName:(NSString *)name age:(NSString *)age gender:(NSString *)gender;

@end

然后實現其中的兩個方法

// NSCoder是iOS中的編碼解碼類
// 歸檔時調用
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.age forKey:@"age"];
    [aCoder encodeObject:self.gender forKey:@"gender"];
}

// 解檔時調用
- (id)initWithCoder:(NSCoder *)aDecoder
{
    NSString *name = [aDecoder decodeObjectForKey:@"name"];
    NSString *age = [aDecoder decodeObjectForKey:@"age"];
    NSString *gender = [aDecoder decodeObjectForKey:@"gender"];
    return [self initWithName:name age:age gender:gender];
}

進行歸檔或者反歸檔

// 歸檔
- (IBAction)archiver:(id)sender {
    // 創建兩個人
    Person *bada = [[Person alloc] initWithName:@"bada" age:@"18" gender:@"男"];
    Person *qiuxiang = [[Person alloc] initWithName:@"qiuxiang" age:@"18" gender:@"女"];
    
    // 獲取到Documents路徑
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    
    // iOS中的歸檔類是NSKeyeArchiver,作用是:將復雜對象轉換為NSData對象
    // 創建一個可變數據對象
    NSMutableData *mData = [NSMutableData data];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:mData];
    // 歸檔時要給歸檔對象添加標記
    [archiver encodeObject:bada forKey:@"bada"];
    [archiver encodeObject:qiuxiang forKey:@"qiuxiang"];
    // 結束歸檔,不管還有多少未歸檔的對象,都不會執行歸檔操作
    [archiver finishEncoding];
    
    // 將數據寫入文件
    // 創建文件路徑
    NSString *filePath = [docPath stringByAppendingPathComponent:@"bada.qiuxiang"];
    [mData writeToFile:filePath atomically:YES];
    
    NSLog(@"歸檔");
}

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

推薦閱讀更多精彩內容