iOS文件管理之沙盒

1.沙盒的基本概念:

ios应用程序只能对自己创建的文件进行读取操作,这个独立的空间,我们称为沙盒,每个应用程序都有自己独立的空间,一般来说应用程序的存储空间是不能相互访问的;

模拟器应用沙盒的位置:/users/username/Library/Application Support/iPhone Simulator

用户根目录下的资源库文件默认是隐藏的,可以通过以下命令来显示和隐藏mac电脑的文件夹:

 

  1. 注意:其中的空格并且区分大小写  
  2. 显示Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles -bool true  
  3.   
  4. 隐藏Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles -bool false  
  5.   
  6. 或者  
  7.   
  8. 显示Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles YES  
  9.   
  10. 隐藏Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles NO输完单击Enter键,退出终端,重新启动Finder就可以了重启Finder:鼠标单击窗口左上角的苹果标志-->强制退出-->Finder-->重新启动  

 

当我们创建我们的应用程序时,在沙盒中会产生三个文件夹:Documents,Library,tmp;

  1. Documents:一般我们需要持久保存的数据存放在里面,里面可以添加子文件夹,需要注意的是在:在iTunes上备份和恢复数据时会对Documents进行备份和恢复;  
  2. Library:用于设置应用程序的默认设置,和其他状态,数据永久保存,与Documents不同的是,在iTunes上备份和恢复数据时不包括此文件夹下的数据;  
  3. tmp:保存一些临时文件的目录,当设备重启时会清空此文件夹下的数据;  

 

2.获取沙盒的目录

  1. 获取程序的根目录(home目录):NSString *homePath = NSHomeDirectory();  
  2. 获取Documents目录:NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask,YES);  
  3.                     NSString *docPath = [paths objectAtIndex:0];或[paths lastObject];    
  4. 获取Library目录:NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory , NSUserDomainMask,YES);  
  5.                     NSString *docPath = [paths objectAtIndex:0];或[paths lastObject];    
  6. 获取Library中Cache目录:NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory , NSUserDomainMask,YES);  
  7.                     NSString *docPath = [paths objectAtIndex:0];或[paths lastObject];    
  8. 获取tmp目录:NSString *tempath = NSTemporaryDirectory();  

 

3.NSString处理路径的方法:

例:NSString *path = @"/Users/apple/text.text";

常用方法:

 
  1. a.获得组成此路径的各个组成成分,结果--("/","Users","apple","text.text");  
  2. - (NSArray *)pathComponents;  
  3. b.提取路径最后的文件名,结果--text.text  
  4. -(NSString *)lastPathComponent;  
  5. c.删除路径最后的文件名,结果--/Users/apple  
  6. -(NSString *)stringByDeletingLastPathComponent;  
  7. d.将str添加到现有路径的末尾,结果--/Users/apple/text.text/addStr  
  8. -(NSString *)stringByAppendingPathComponent:(NSString *)addStr;  
  9. e.获取路径最后文件的扩展名,结果--text  
  10. -(NSString *)pathExtension;  
  11. f.删除路径最后的扩展名,结果--/Users/apple/text  
  12. -(NSString *)stringByDeletingPathExtension;  
  13. g.在路径最后添加扩展名,结果--/Users/apple/text.text.app  
  14. -(NSString *)stringByAddendingPahtExtension:(NSString *)str;  

 

4.NSFileManager对文件的基本操作

 
  1. a.创建一个文件并写入数据  
  2. -(BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data attributes:(NSDictionary *)attr;  
  3.   
  4. b.从一个文件中读取数据  
  5. -(NSData *)contentsAtPath:(NSString *)path;  
  6.   
  7. c.文件移动,从srcPath路径上移动到dstPath路径上,这里是文件路径,而不是目录路径,没有文件,先创建文件;  
  8. - (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error ;  
  9.   
  10. d.比较两个文件的内容是否一样  
  11. - (BOOL)contentsEqualAtPath:(NSString *)path1 andPath:(NSString *)path2;  
  12.   
  13. e.判断文件是否存在  
  14. - (BOOL)fileExistsAtPath:(NSString *)path;  
  15.   
  16. f.删除文件  
  17. - (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error;  
  18.   
  19. g.获取文件大小  
  20.  NSFileManager *fileManager = [NSFileManager defaultManager];  
  21. NSDIctionary *attrDic = [fileManager attributesOfItemAtPath:filePath error:nil];  
  22. NSNumber *fileSize = [attrDic objectForKey:NSFileSize];  


5.NSFileHandle对文件的基本操作

 

NSFileManager主要对文件进行操作(文件的创建,删除,修改,移动,复制)

NSFileHandle主要对文件内容进行读取

NSFileHandle操作文件的步骤:a.创建一个NSFileHandle对象  b.对打开的文件进行I/O操作 c.关闭文件

NSFileHandle只能读写文件,不能创建文件

常用的文件处理:

 
    1. + (id)fileHandleForReadingAtPath:(NSString *)path;//打开一个文件读取  
    2. + (id)fileHandleForWritingAtPath:(NSString *)path;//打开一个文件写入  
    3. + (id)fileHandleForUpdatingAtPath:(NSString *)path;//打开一个文件更新  
    4.   
    5. - (NSData *)availableData; //返回所有可用数据  
    6. - (NSData *)readDataToEndOfFile;//从当前节点读取到文件末尾  
    7. - (NSData *)readDataOfLength:(NSUInteger)length;//从当前节点读取指定长度的数据  
    8. - (void)writeData:(NSData *)data;// 写入数据  
    9. - (unsigned long long)offsetInFile;// 获取文件当前的偏移量,也就是文件当前读取到什么位置  
    10. - (unsigned long long)seekToEndOfFile;// 跳转到文件末尾  
    11. - (void)seekToFileOffset:(unsigned long long)offset;// 将文件长度设置为offset字节  
    12.   
    13. - (void)closeFile;//关闭文件  
    14. iPhone文件系统NSFileManager讲解是本文要介绍的内容,主要是通过iphone文件系统来学习NSFileManager的使用方法,具体内容来看本文详解。

      iPhone文件系统:创建、重命名以及删除文件,NSFileManager中包含了用来查询单词库目录、创建、重命名、删除目录以及获取/设置文件属性的方法(可读性,可编写性等等)。

      每个程序都会有它自己的沙盒,通过它你可以阅读/编写文件。写入沙盒的文件在程序的进程中将会保持稳定,即便实在程序更新的情况下。

      如下所示,你可以在沙盒中定位文件目录:

      1. //对于错误信息  
      2. NSError *error;  
      3. // 创建文件管理器  
      4. NSFileManager *fileMgr = [NSFileManagerdefaultManager];  
      5. //指向文件目录  
      6. NSString *documentsDirectory= [NSHomeDirectory()   
      7. stringByAppendingPathComponent:@"Documents"];  
      8.  
      9. //创建一个目录  
      10. [[NSFileManager defaultManager]   createDirectoryAtPath: [NSString stringWithFormat:@"%@/myFolder", NSHomeDirectory()] attributes:nil]; 

      创建一个文件

      现在我们已经有了文件目录,我们就能使用这个路径在沙盒中创建一个新文件并编写一段代码:

      1. // File we want to create in the documents directory我们想要创建的文件将会出现在文件目录中  
      2. // Result is: /Documents/file1.txt结果为:/Documents/file1.txt  
      3. NSString *filePath= [documentsDirectory  
      4. stringByAppendingPathComponent:@"file1.txt"];  
      5. //需要写入的字符串  
      6. NSString *str= @"iPhoneDeveloper Tips\nhttp://iPhoneDevelopTips,com";  
      7. //写入文件  
      8. [str writeToFile:filePath atomically:YES   
      9. encoding:NSUTF8StringEncoding error:&error];  
      10. //显示文件目录的内容  
      11. NSLog(@"Documentsdirectory: %@",  
      12. [fileMgr contentsOfDirectoryAtPath:documentsDirectoryerror:&error]); 

      我们为想要创建的文件构建一条路径(file1.txt),初始化一个字符串来写入文件,并列出目录。最后一行显示了在我们创建文件之后出现在文件目录下的一个目录列表:

      对一个文件重命名

      想要重命名一个文件,我们需要把文件移到一个新的路径下。下面的代码创建了我们所期望的目标文件的路径,然后请求移动文件以及在移动之后显示文件目录。

      1. //通过移动该文件对文件重命名  
      2. NSString *filePath2= [documentsDirectory  
      3. stringByAppendingPathComponent:@"file2.txt"];  
      4. //判断是否移动  
      5. if ([fileMgr moveItemAtPath:filePath toPath:filePath2 error:&error] != YES)  
      6. NSLog(@"Unable to move file: %@", [error localizedDescription]);  
      7. //显示文件目录的内容  
      8. NSLog(@"Documentsdirectory: %@",   
      9. [fileMgr contentsOfDirectoryAtPath:documentsDirectoryerror:&error]); 

      在移动了文件之后,输出结果应该如下图所示:

      删除一个文件

      为了使这个技巧完整,让我们再一起看下如何删除一个文件:

      1. //在filePath2中判断是否删除这个文件  
      2. if ([fileMgr removeItemAtPath:filePath2 error:&error] != YES)  
      3. NSLog(@"Unable to delete file: %@", [error localizedDescription]);  
      4. //显示文件目录的内容  
      5. NSLog(@"Documentsdirectory: %@",  
      6. [fileMgr contentsOfDirectoryAtPath:documentsDirectoryerror:&error]); 

      一旦文件被删除了,正如你所预料的那样,文件目录就会被自动清空:

      这些示例能教你的,仅仅只是文件处理上的一些皮毛。想要获得更全面、详细的讲解,你就需要掌握NSFileManager文件的知识。

      在开发iPhone程序时,有时候要对文件进行一些操作。而获取某一个目录中的所有文件列表,是基本操作之一。通过下面这段代码,就可以获取一个目录内的文件及文件夹列表。

      1. NSFileManager *fileManager = [NSFileManager defaultManager];  
      2. //在这里获取应用程序Documents文件夹里的文件及文件夹列表  
      3.         NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
      4.         NSString *documentDir = [documentPaths objectAtIndex:0];  
      5.         NSError *error = nil;  
      6.         NSArray *fileList = [[NSArray alloc] init];  
      7. //fileList便是包含有该文件夹下所有文件的文件名及文件夹名的数组  
      8.         fileList = [fileManager contentsOfDirectoryAtPath:documentDir error:&error]; 

      以下这段代码则可以列出给定一个文件夹里的所有子文件夹名

      1. NSMutableArray *dirArray = [[NSMutableArray alloc] init];  
      2.         BOOL isDir = NO;  
      3. //在上面那段程序中获得的fileList中列出文件夹名  
      4.         for (NSString *file in fileList) {  
      5.                 NSString *path = [documentDir stringByAppendingPathComponent:file];  
      6.                 [fileManager fileExistsAtPath:path isDirectory:(&isDir)];  
      7.                 if (isDir) {  
      8.                         [dirArray addObject:file];  
      9.                 }  
      10.                 isDir = NO;  
      11.         }  
      12.         NSLog(@"Every Thing in the dir:%@",fileList);  
      13.         NSLog(@"All folders:%@",dirArray); 
    15. 我们看看NSFileManager如何使用。包括创建文件,目录,删除,遍历目录等。

       

      1、在Documents里创建目录

      创建一个叫test的目录,先找到Documents的目录,

       

      1. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);    
      2.    NSString *documentsDirectory = [paths objectAtIndex:0];    
      3.    NSLog(@"documentsDirectory%@",documentsDirectory);    
      4.    NSFileManager *fileManager = [NSFileManager defaultManager];    
      5.    NSString *testDirectory = [documentsDirectory stringByAppendingPathComponent:@"test"];    
      6.    // 创建目录  
      7.    [fileManager createDirectoryAtPath:testDirectory withIntermediateDirectories:YES attributes:nil error:nil];  

       

      启动程序,这时候目录就创建了:

       

      2、在test目录下创建文件

      创建文件怎么办呢?接着上面的代码 testPath 要用stringByAppendingPathComponent拼接上你要生成的文件名,比如test00.txt。这样才能在test下写入文件。

       

      testDirectory是上面代码生成的路径哦,不要忘了。我往test文件夹里写入三个文件,test00.txt ,test22.txt,text.33.txt。内容都是写入内容,write String。

      实现代码如下:

       

      1. NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test00.txt"];    
      2. NSString *testPath2 = [testDirectory stringByAppendingPathComponent:@"test22.txt"];    
      3. NSString *testPath3 = [testDirectory stringByAppendingPathComponent:@"test33.txt"];    
      4.   
      5.   
      6. NSString *string = @"写入内容,write String";  
      7. [fileManager createFileAtPath:testPath contents:[string  dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];  
      8. [fileManager createFileAtPath:testPath2 contents:[string  dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];  
      9. [fileManager createFileAtPath:testPath3 contents:[string  dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];  
      看下面的图,三个文件都出来了,内容也对。

       

      在Documents目录下创建就更简单了,不用加test就ok了

      3、获取目录列里所有文件名

      两种方法获取:subpathsOfDirectoryAtPath 和 subpathsAtPath

       

      1. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);    
      2. NSString *documentsDirectory = [paths objectAtIndex:0];    
      3. NSLog(@"documentsDirectory%@",documentsDirectory);    
      4. NSFileManager *fileManage = [NSFileManager defaultManager];    
      5. NSString *myDirectory = [documentsDirectory stringByAppendingPathComponent:@"test"];    
      6. NSArray *file = [fileManage subpathsOfDirectoryAtPath: myDirectory error:nil];   
      7. NSLog(@"%@",file);    
      8. NSArray *files = [fileManage subpathsAtPath: myDirectory ];   
      9. NSLog(@"%@",files);  

      获取上面刚才test文件夹里的文件名

      打印结果

       

      2012-06-17 23:23:19.684 IosSandbox[947:f803] fileList:(

          ".DS_Store",

          "test00.txt",

          "test22.txt",

          "test33.txt"

      )

      2012-06-17 23:23:19.686 IosSandbox[947:f803] fileLit(

          ".DS_Store",

          "test00.txt",

          "test22.txt",

          "test33.txt"

      )

      两个方法都可以,隐藏的文件也打印出来了。

      4、fileManager使用操作当前目录

       

      1. //创建文件管理器  
      2.     NSFileManager *fileManager = [NSFileManager defaultManager];  
      3.     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
      4.     NSString *documentsDirectory = [paths objectAtIndex:0];  
      5.     //更改到待操作的目录下  
      6.     [fileManager changeCurrentDirectoryPath:[documentsDirectory stringByExpandingTildeInPath]];  
      7.     //创建文件fileName文件名称,contents文件的内容,如果开始没有内容可以设置为nil,attributes文件的属性,初始为nil  
      8.     NSString * fileName = @"testFileNSFileManager.txt";  
      9.     NSArray *array = [[NSArray alloc] initWithObjects:@"hello world",@"hello world1", @"hello world2",nil];  
      10.     [fileManager createFileAtPath:fileName contents:array attributes:nil];  
      这样就创建了testFileNSFileManager.txt并把三个hello world写入文件了

       

       

      changeCurrentDirectoryPath目录更改到当前操作目录时,做文件读写就很方便了,不用加上全路径

      5、删除文件

      接上面的代码,remove就ok了。

       

      1. [fileManager removeItemAtPath:fileName error:nil];  
      6、混合数据的读写

       

      用NSMutableData创建混合数据,然后写到文件里。并按数据的类型把数据读出来

      6.1写入数据:

       

      1. NSString * fileName = @"testFileNSFileManager.txt";  
      2. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
      3. NSString *documentsDirectory = [paths objectAtIndex:0];  
      4. //获取文件路径  
      5. NSString *path = [documentsDirectory stringByAppendingPathComponent:fileName];  
      6. //待写入的数据  
      7. NSString *temp = @"nihao 世界";  
      8. int dataInt = 1234;  
      9. float dataFloat = 3.14f;  
      10. //创建数据缓冲  
      11. NSMutableData *writer = [[NSMutableData alloc] init];  
      12. //将字符串添加到缓冲中  
      13. [writer appendData:[temp dataUsingEncoding:NSUTF8StringEncoding]];     
      14. //将其他数据添加到缓冲中  
      15. [writer appendBytes:&dataInt length:sizeof(dataInt)];  
      16. [writer appendBytes:&dataFloat length:sizeof(dataFloat)];    
      17. //将缓冲的数据写入到文件中  
      18. [writer writeToFile:path atomically:YES];  

      我们看看数据怎么样了:

       


      我们看到后面的是乱码,那是中文被转成了NSData后,还有int float的二进制

      6.2读取刚才写入的数据:

       

       
      1. //读取数据:  
      2.    int intData;  
      3.    float floatData = 0.0;  
      4.    NSString *stringData;  
      5.      
      6.    NSData *reader = [NSData dataWithContentsOfFile:path];  
      7.    stringData = [[NSString alloc] initWithData:[reader subdataWithRange:NSMakeRange(0, [temp length])]  
      8.                                   encoding:NSUTF8StringEncoding];  
      9.    [reader getBytes:&intData range:NSMakeRange([temp length], sizeof(intData))];  
      10.    [reader getBytes:&floatData range:NSMakeRange([temp length] + sizeof(intData), sizeof(floatData))];  
      11.    NSLog(@"stringData:%@ intData:%d floatData:%f", stringData, intData, floatData);  

      打印出来的结果:

       

      2012-06-17 23:51:14.723 IosSandbox[1285:f803] stringData:nihao hello! intData:1234332 floatData:3.140000

      这里把写入的汉字改成了 hello。因为[temp length]算长度是,把中文算成一位了,出来的结果有误。

       

       

      例子代码:https://github.com/schelling/YcDemo

posted on 2015-12-04 15:35  没有14  阅读(94)  评论(0)    收藏  举报

导航