简介:
iOS基于OS X,而OSX本身基于Unix操作系统。在iOS里面,操作系统的完全路径结构是不可见的,因为每个APP的数据都存储自身的沙盒里面。沙盒环境实际上听起来像这样:一个只允许当前APP访问的文件夹目录。每个APP都有自身的沙盒文件夹,并且沙盒文件夹下的子文件夹只有当前APP能够访问。
当一个iOS APP在设备上安装后,系统为其创建的文件夹结构如下:
XXX.app即Main BundleDocuments/存储用户创建的内容Library/存储缓存文件、偏好设置等等每个应用的根文件夹包含各种其他文件夹,下面是一些解释:
Library/Caches/存储重复创建的缓存文件磁盘空间不足且应用不在运行状态时,该目录下文件可能会被删除,切记Library/PReferences/存储偏好设置Library/applicationSupport/不会自动创建tmp/临时文件现在你知道当APP在设备上安装后,系统为你创建了哪些文件夹。下一步你也许会想知道,如何找到这些文件夹的路径。
/*
本文翻译自《iOS 7 Programming Cookbook》一书的第14章“Files and Folder Management ”,想体会原文精髓的朋友请支持原书正版。
——————(博客园、新浪微博)葛布林大帝
*/
目录:
一. 获取常用文件夹的路径
二. 写入和读取文件
三. 创建文件夹
四. 枚举文件/文件夹
五. 删除文件/文件夹
六. 存储对象到文件
本书源代码:https://github.com/oreillymedia/iOS7_Programming_Cookbook
一、获取常用文件夹的路径
问题:
你想找到可用文件夹的路径
解决方案:
使用NSFileManager类的实例方法URLsForDirectory:inDomains:
讨论:
NSFileManager类提供了许多与文件/文件夹相关的操作,我不建议使用这个类提供的defaultManager类方法来进行文件管理,因为它不是线程安全的。
NSFileManager类的URLsForDirectory:inDomains:实例方法常被用来搜索iOS文件系统的指定目录,其中两个参数如下:
URLsForDirectory:想要搜索的目录参数值为NSSearchPathDirectory类型的枚举inDomains想要寻找的指定目录参数值为NSSearchPathDomainMask类型的枚举
1.Documents文件夹
假设你想要找出Documents文件夹的路径,代码如下:
1NSFileManager *fileManager =[[NSFileManager alloc] init];2NSArray *urls =[fileManager URLsForDirectory:NSDocumentDirectory3inDomains:NSUserDomainMask];45if([urls count] >0){6NSURL *documentsFolder = urls[0];7NSLog(@"%@", documentsFolder);8}else{9NSLog(@"Could not find the Documents folder.");10}
运行代码,你应该得到了Document文件夹的路径。现在我们来看看URLsForDirectory:inDomains:方法的常用参数:
URLsForDirectoryNSLibraryDirectoryLibrary文件夹NSCachesDirectoryCaches文件夹NSDocumentDirectoryDocuments文件夹inDomainsNSUserDomainMask在当前用户文件夹里执行指定搜索在OS X里,这个文件夹为~/
2.Caches文件夹
使用这个方法,你也可以找到Caches文件夹,以此类推:
1NSFileManager *fileManager =[[NSFileManager alloc] init];2NSArray *urls =[fileManager URLsForDirectory:NSCachesDirectory3inDomains:NSUserDomainMask];45if([urls count] >0){6NSURL *cachesFolder = urls[0];7NSLog(@"%@", cachesFolder);8}else{9NSLog(@"Could not find the Caches folder.");10}
3.tmp文件夹
如果你想要找到tmp文件夹,使用C函数NSTemporaryDirectory():
1NSString *tempDirectory =NSTemporaryDirectory();2NSLog(@"Temp Directory = %@", tempDirectory);
二、写入和读取文件
问题:
你想存储信息到磁盘(如text、data、images等等)
解决方案:
Cocoa类允许你存储信息,例如NSString、UIImage和NSData,所有公开的实例方法允许你存储这些数据到指定的路径。
讨论
为了存储text到磁盘,假设把text作为一个NSString变量来存储,可以使用这个类的实例方法writeToFile:atomically:en coding:error:,参数如下:
writeToFile要写入的路径,类型为NSStringatomicallyBOOL类型。如果设为YES,会写入文件到一个临时空间,并且在存储到目的地后移除临时文件encoding编码模式,通常使用NSUTF8StringEncodingerror存储失败时,使用一个指针指向NSError对象
1.存储NSString
例如,如果想要临时存储一些text,并不需要备份,代码如下:
1NSString *someText =@"Random string that won't be backed up.";2NSString *destinationPath =3[NSTemporaryDirectory()4stringByAppendingPathComponent:@"MyFile.txt"];56NSError *error =nil;7BOOL succeeded =[someText writeToFile:destinationPath8atomically:YES9encoding:NSUTF8StringEncoding10error:&error];1112if(succeeded) {13NSLog(@"Successfully stored the file at: %@", destinationPath);14}else{15NSLog(@"Failed to store the file. Error = %@", error);16}
2.从文件读取NSString
完成上面的存储后,你可以使用NSString类的stringWithContentsOfFile:encoding:error:类方法获取指定文件的路径。
如果你想从一个文件读取NSString内容,可以使用NSString类的实例方法initWithContentsOfFile:encoding:error:,代码如下:
1- (BOOL) writeText:(NSString *)paramText toPath:(NSString *)paramPath{2return[paramText writeToFile:paramPath3atomically:YES4encoding:NSUTF8StringEncoding5error:nil];6}7- (NSString *) readTextFromPath:(NSString *)paramPath{8return[[NSString alloc] initWithContentsOfFile:paramPath9encoding:NSUTF8StringEncoding10error:nil];11}1213- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{14NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"MyFile.txt"];1516if([self writeText:@"Hello, World!"toPath:filePath]){17NSString *readText =[self readTextFromPath:filePath];18if([readText length] >0){19NSLog(@"Text read from disk = %@", readText);20}else{21NSLog(@"Failed to read the text from disk.");22}2324}else{25NSLog(@"Failed to write the file.");26}2728self.window =[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];29self.window.backgroundColor =[UIColor whiteColor]; [30self.window makeKeyAndVisible];returnYES;31}
上面创建了两个便利方法,允许我们从指定位置写入和读取文本。
如果你想使用NSURL的实例,可以使用writeToURL:atomically:encoding:error:实例方法来代替。
3.写入和读取NSArray
Foundation其他类的写入方法类似NSString,对于NSArray,可以使用实例方法writeToFile:atom ically:。
为了从磁盘读取array的内容,可以使用初始化方法initWithContentsOfFile:,代码如下:
1NSString *filePath =[NSTemporaryDirectory()2stringByAppendingPathComponent:@"MyFile.txt"];34NSArray *arrayOfNames = @[@"Steve",@"John",@"Edward"];5if([arrayOfNames writeToFile:filePath atomically:YES]){6NSArray *readArray =[[NSArray alloc] initWithContentsOfFile:filePath];7if([readArray count] ==[arrayOfNames count]){8NSLog(@"Read the array back from disk just fine.");9}else{10NSLog(@"Failed to read the array back from disk.");11}12}else{13NSLog(@"Failed to save the array to disk.");14}
NSArray的实例方法writeToFile:atomically:可以存储包含下列类型对象的数组:
NSStringNSDictionaryNSArrayNSDataNSNumberNSData
4.写入和读取NSDictionary
字典的读写操作与数组十份相似,代码如下:
1NSString *filePath =[NSTemporaryDirectory()2stringByAppendingPathComponent:@"MyFile.txt"];3NSDictionary *dict =@{4@"first name":@"Steven",5@"middle name":@"Paul",6@"last name":@"Jobs",7};89if([dict writeToFile:filePath atomically:YES]){10NSDictionary *readDictionary =[[NSDictionary alloc]11initWithContentsOfFile:filePath];1213/*Now compare the dictionaries and see if the one we read from disk is the same as the one we saved to disk*/14if([readDictionary isEqualToDictionary:dict]){15NSLog(@"The file we read is the same one as the one we saved.");16}else{17NSLog(@"Failed to read the dictionary from disk.");18}19}else{20NSLog(@"Failed to write the dictionary to disk.");21}
5.char与NSData
想要写入一个char类型,可以使用NSData,代码如下:
1NSString *filePath =[NSTemporaryDirectory()2stringByAppendingPathComponent:@"MyFile.txt"];34charbytes[4] = {'a','b','c','d'};56NSData *dataFromBytes =[[NSData alloc] initWithBytes:bytes7length:sizeof(bytes)];89if([dataFromBytes writeToFile:filePath atomically:YES]){10NSData *readData =[[NSData alloc] initWithContentsOfFile:filePath];11if([readData isEqualToData:dataFromBytes]){12NSLog(@"The data read is the same data as was written to disk.");13}else{14NSLog(@"Failed to read the data from disk.");15}16}else{17NSLog(@"Failed to save the data to disk.");18}