首页 > 代码库 > (转载)OC学习篇之---文件的操作
(转载)OC学习篇之---文件的操作
前一篇文章中我们讲到了OC中的归档和解档操作,今天我们来介绍OC中文件操作,在之前的文章中,已经接触到了文件的创建了,但是那不是很具体和详细,这篇文章我们就来仔细看一下OC中是如何操作文件的:
第一、首先来看一下本身NSString类给我们提供了哪些可以操作文件路径名的方法
1 // 2 // main.m 3 // 37_FilePathHandle 4 // 5 // Created by jiangwei on 14-10-13. 6 // Copyright (c) 2014年 jiangwei. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 11 int main(int argc, const charchar * argv[]) { 12 @autoreleasepool { 13 14 //演示路径 15 NSString *path = @"/Users/jiangwei/file.text"; 16 17 //1.返回路径的组成部分 18 NSArray *array = [path pathComponents]; 19 NSLog(@"%@",array); 20 21 //2.返回路径最后组成部分 22 NSString *str = [path lastPathComponent]; 23 NSLog(@"%@",str); 24 25 //3.在原有的路径后面追加子目录 26 //这种方式有一点不好,就是需要添加/ 27 [path stringByAppendingString:@"/appFile.text"]; 28 //不需要添加/ 29 [path stringByAppendingPathComponent:@"appFile.text"]; 30 31 //4.删除最后的组成部分 32 str = [path stringByDeletingLastPathComponent]; 33 //删除扩展名(.text被删除了) 34 str = [path stringByDeletingPathExtension]; 35 36 //5.获取扩展名 37 str = [path pathExtension]; 38 39 //6.添加扩展名 40 [path stringByAppendingPathExtension:@".jpg"]; 41 42 } 43 return 0; 44 }
在Java中,我们知道,当我们去操作一个文件的时候,最开始的时候肯定要去构建一个路径,这个路径一般都是String类型的,我们需要定义不同的路径和文件名,OC中也不例外,不过OC中的NSString类在这方面做的可能会更好,下面依次来看一下他的方法:
1、将路径进行分割
1 //演示路径 2 NSString *path = @"/Users/jiangwei/file.text"; 3 4 //1.返回路径的组成部分 5 NSArray *array = [path pathComponents]; 6 NSLog(@"%@",array);
运行结果:
返回的一个数组,将路径分割了,但是需要注意的是,第一个是"/",这个也算是路径的一部分。
2、返回路径的最后组成部分
1 //2.返回路径最后组成部分 2 NSString *str = [path lastPathComponent]; 3 NSLog(@"%@",str);
运行结果:
这个直接返回路径的最后一部分,这个如果放在Java中,我们可能需要用到String类的字符串分割技术了,没有这里的方便
3、添加子目录/子文件
1 //3.在原有的路径后面追加子目录 2 //这种方式有一点不好,就是需要添加/ 3 //演示路径 4 str = [path stringByAppendingString:@"/appFile.text"]; 5 NSLog(@"%@",str); 6 //不需要添加/ 7 str = [path stringByAppendingPathComponent:@"appFile.text"]; 8 NSLog(@"%@",str);
这里其实有两种方式可以添加,第一种是直接使用拼接字符串的方式,但是需要手动的添加"/",第二种方式是NSString提供的,不需要手动的添加"/"
运行结果:
4、删除最后面的部分和后缀名
1 //4.删除最后的组成部分 2 str = [path stringByDeletingLastPathComponent]; 3 NSLog(@"%@",str); 4 //删除扩展名(.text被删除了) 5 str = [path stringByDeletingPathExtension]; 6 NSLog(@"%@",str);
运行结果:
5、获取扩展名
1 //5.获取扩展名 2 str = [path pathExtension]; 3 NSLog(@"%@",str);
运行结果:
6、添加扩展名
1 //6.添加扩展名 2 str = [path stringByAppendingPathExtension:@"jpg"]; 3 NSLog(@"%@",str);
运行结果:
上面就是总结了NSString类中操作文件路径的一些方法,其实这些操作如果放在Java中做的话,就是需要使用String的分割,拼接等技术了。这里看到OC给我们提供了便捷
第二、在来看一下操作文件之前需要了解的一个对象:NSData
这个类的作用就是将我们写入到文件中的数据进行编码和解码操作:
1 // 2 // main.m 3 // 38_NSData 4 // 5 // Created by jiangwei on 14-10-13. 6 // Copyright (c) 2014年 jiangwei. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 11 //NSData类型 12 //是一种存储形式 13 int main(int argc, const charchar * argv[]) { 14 @autoreleasepool { 15 //存储是有编码方式的,编程字节码 16 //相当于Java中的解码和编码 17 NSString *s = @"tsdfsdfsdfsdf"; 18 NSData *data =http://www.mamicode.com/ [s dataUsingEncoding:NSUTF8StringEncoding]; 19 s = [[NSString alloc] initWithData:data encoding:(NSUTF8StringEncoding)]; 20 21 //可变对象 NSMutableData 可以追加数据 22 } 23 return 0; 24 }
这个和Java中String直接在构造的时候就可以进行编码和解码了,这里需要使用中间类NSData,当然这个类是不可变的,如果想追加内容的话,需要使用NSMutableData类
第三、说完了NSData这个中间类,下面来正式说文件的操作了
但是这里对文件的操作,我们放到IOS平台去操作,因为我们后面也是会介绍IOS中文件的操作,所以就直接在这里说了,当然这里的知识会有点冲突,但是我们不关心IOS中的其他技术,只看他的文件操作:
1、沙盒文件
在IOS中,每个应用程序都是一个沙盒,他们有自己的文件目录,这个目录对其他程序是不可见的,和Android中的/data/data/包名/中的内容差不多,当然IOS中的沙盒目录有三种:
Documents:存放长期使用的文件(一般存放目录)
Library:系统存放文件
tmp:临时文件,app重启时,该目录下得文件清空
下面来看一个简单的例子吧:
1 // 2 // main.m 3 // 36_SandBoxFile 4 // 5 // Created by jiangwei on 14-10-13. 6 // Copyright (c) 2014年 jiangwei. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 #import "AppDelegate.h" 11 12 int main(int argc, charchar * argv[]) { 13 @autoreleasepool { 14 //获取沙盒目录 15 //默认有三个文件夹 16 //Documents:存放长期使用的文件(一般存放目录) 17 //Library:系统存放文件 18 //tmp:临时文件,app重启时,该目录下得文件清空 19 20 //第一种获取方式,我们得到Home目录之后,手动的去拼接Document/Library 21 NSString *homePath = NSHomeDirectory(); 22 NSLog(@"沙盒目录:%@",homePath); 23 24 //第二种方式,直接使用Api获取 25 //NSDocumentDirectory:Documents文件夹 26 //NSLibraryDirectory:Library文件夹 27 NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 28 NSLog(@"%@",array); 29 30 NSArray *array1 = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); 31 NSLog(@"%@",array1); 32 33 return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 34 } 35 }
创建IOS项目和OC差不多:
后续的操作就一样了,创建完之后的项目结构:
我们在main.m文件中写我们的代码就可以了。
下面来看代码:
1 //第一种获取方式,我们得到Home目录之后,手动的去拼接Document/Library 2 NSString *homePath = NSHomeDirectory(); 3 NSLog(@"沙盒目录:%@",homePath);
获取沙盒的home目录,然后我们可以操作在其下面创建子目录了。
这里有两种方式去创建Document等目录,一种是我们用上面NSString类提供的方法去手动拼接目录,还有一种是用系统给我们提供的方法,这两种都是可以的。
1 //第二种方式,直接使用Api获取 2 //NSDocumentDirectory:Documents文件夹 3 //NSLibraryDirectory:Library文件夹 4 NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 5 NSLog(@"%@",array); 6 7 NSArray *array1 = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); 8 NSLog(@"%@",array1);
看一下运行结果:
第四、了解了程序的沙盒目录,下面继续来看一下操作文件的两个类
一、NSFileManager
这个类的主要功能是对文件进行操作:创建,复制,剪切,删除等。
看代码:
1 // 2 // main.m 3 // 39_NSFileManager 4 // 5 // Created by jiangwei on 14-10-13. 6 // Copyright (c) 2014年 jiangwei. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 #import "AppDelegate.h" 11 12 //NSFileManager:对文件进行操作的,包括复制,粘贴,删除,剪切等操作 13 int main(int argc, charchar * argv[]) { 14 @autoreleasepool { 15 16 //------------------创建文件/文件夹 17 //获取沙盒目录 18 NSString *homePath = NSHomeDirectory(); 19 //在沙盒目录中创建一个文件file.text 20 NSString *filePath = [homePath stringByAppendingPathComponent:@"Documents/file.text"]; 21 //NSFileManager是单利模式,所以不能使用alloc+init创建 22 NSFileManager *manager = [NSFileManager defaultManager]; 23 NSString *str = @"无线互联"; 24 NSData *data =http://www.mamicode.com/ [str dataUsingEncoding:NSUTF8StringEncoding]; 25 //参数:文件路径、文件内容、文件的属性 26 BOOL sucess = [manager createFileAtPath:filePath contents:data attributes:nil]; 27 if(sucess){ 28 NSLog(@"文件创建成功"); 29 }else{ 30 NSLog(@"文件创建失败"); 31 } 32 33 //创建文件夹 34 NSString *filePaths = [homePath stringByAppendingPathComponent:@"Documents/file"]; 35 NSError *error; 36 //需要传递一个创建失败的指针对象,记录创建失败的信息 37 BOOL success1 = [manager createDirectoryAtPath:filePaths withIntermediateDirectories:YES attributes:nil error:&error]; 38 if(!success1){ 39 NSLog(@"创建成功"); 40 }else{ 41 NSLog(@"创建失败"); 42 } 43 44 45 //--------------------读取文件 46 //根据路径读取文件内容 47 NSData *datas = [manager contentsAtPath:filePath]; 48 NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 49 NSLog(@"%@",s); 50 51 52 //--------------------移动文件/剪切文件 53 //NSFileManager中没有提供重命名的方法,所以我们可以借助移动的api进行操作 54 //把filePath移动到targetPath目录中 55 NSString *targetPath = [homePath stringByAppendingPathComponent:@"Documents/file/file2.text"]; 56 BOOL sucess2 = [manager moveItemAtPath:filePath toPath:targetPath error:nil]; 57 if(sucess2) { 58 NSLog(@"移动成功"); 59 }else{ 60 NSLog(@"移动失败"); 61 } 62 63 64 //--------------------复制文件 65 BOOL sucess3 = [manager copyItemAtPath:filePath toPath:targetPath error:nil]; 66 if(sucess3){ 67 //复制成功 68 }else{ 69 //复制失败 70 } 71 72 73 //--------------------删除文件 74 //删除之前需要判断这个文件是否存在 75 BOOL isExist = [manager fileExistsAtPath:filePath];//判断文件是否存在 76 if(isExist){ 77 BOOL sucess4 = [manager removeItemAtPath:filePath error:nil]; 78 if(sucess4){ 79 //删除成功 80 }else{ 81 //删除失败 82 } 83 } 84 85 86 //--------------------获取文件的属性 87 NSDictionary *dic = [manager attributesOfItemAtPath:filePath error:nil]; 88 NSLog(@"%@",dic);//通过打印我们就可以查看文件属性的一些key 89 90 return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 91 } 92 }
1、创建文件
1 //------------------创建文件/文件夹 2 //获取沙盒目录 3 NSString *homePath = NSHomeDirectory(); 4 //在沙盒目录中创建一个文件file.text 5 NSString *filePath = [homePath stringByAppendingPathComponent:@"Documents/file.text"]; 6 //NSFileManager是单利模式,所以不能使用alloc+init创建 7 NSFileManager *manager = [NSFileManager defaultManager]; 8 NSString *str = @"无线互联"; 9 NSData *data =http://www.mamicode.com/ [str dataUsingEncoding:NSUTF8StringEncoding]; 10 //参数:文件路径、文件内容、文件的属性 11 BOOL sucess = [manager createFileAtPath:filePath contents:data attributes:nil]; 12 if(sucess){ 13 NSLog(@"文件创建成功"); 14 }else{ 15 NSLog(@"文件创建失败"); 16 }
NSFileManager内部使用了单例模式,这个后面会说到OC中得单例模式,然后就是构建一个NSData类,最后使用createFileAtPath方法创建文件,不过最后的attributes参数一般是用来给这个文件定义一些属性的,当然文件本身也是有很多默认的属性,比如文件的大小,文件的创建日期等,我们也可以自己在追加一些属性。
2、创建文件夹
1 //创建文件夹 2 NSString *filePaths = [homePath stringByAppendingPathComponent:@"Documents/file"]; 3 NSError *error; 4 //需要传递一个创建失败的指针对象,记录创建失败的信息 5 BOOL success1 = [manager createDirectoryAtPath:filePaths withIntermediateDirectories:YES attributes:nil error:&error]; 6 if(!success1){ 7 NSLog(@"创建成功"); 8 }else{ 9 NSLog(@"创建失败"); 10 }
从这两个操作看出来,他和Java中的File类很相似的
3、读取文件
1 //--------------------读取文件 2 //根据路径读取文件内容 3 NSData *datas = [manager contentsAtPath:filePath]; 4 NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 5 NSLog(@"%@",s);
4、剪切文件
1 //--------------------移动文件/剪切文件 2 //NSFileManager中没有提供重命名的方法,所以我们可以借助移动的api进行操作 3 //把filePath移动到targetPath目录中 4 NSString *targetPath = [homePath stringByAppendingPathComponent:@"Documents/file/file2.text"]; 5 BOOL sucess2 = [manager moveItemAtPath:filePath toPath:targetPath error:nil]; 6 if(sucess2) { 7 NSLog(@"移动成功"); 8 }else{ 9 NSLog(@"移动失败"); 10 }
这里有两个参数:一个是需要移动文件的路径,和需要移动到哪的路径
5、复制文件
1 //--------------------复制文件 2 BOOL sucess3 = [manager copyItemAtPath:filePath toPath:targetPath error:nil]; 3 if(sucess3){ 4 //复制成功 5 }else{ 6 //复制失败 7 }
6、删除文件
1 //--------------------删除文件 2 //删除之前需要判断这个文件是否存在 3 BOOL isExist = [manager fileExistsAtPath:filePath];//判断文件是否存在 4 if(isExist){ 5 BOOL sucess4 = [manager removeItemAtPath:filePath error:nil]; 6 if(sucess4){ 7 //删除成功 8 }else{ 9 //删除失败 10 } 11 }
7、操作文件的属性
1 //--------------------获取文件的属性 2 NSDictionary *dic = [manager attributesOfItemAtPath:filePath error:nil]; 3 NSLog(@"%@",dic);//通过打印我们就可以查看文件属性的一些key
属性一般是NSDictionary
二、NSFileHandle
这个类主要是对文件进行读写操作的。
看代码:
1 // 2 // main.m 3 // 40_NSFileHandle 4 // 5 // Created by jiangwei on 14-10-13. 6 // Copyright (c) 2014年 jiangwei. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 #import "AppDelegate.h" 11 12 //写文件,我们之前使用各种数据结构来存储数据:NSString,NSData,NSDictionary,NSArray等,他们都是有一个writeToFile方法用来写文件的 13 14 //纯文本:没有任何格式的数据 15 //非纯文本:有修饰的数据(字体大小,字体颜色等) 16 17 //数组只能将如下类型写入文件,如果包含其他对象,将写入失败:NSNumber,NSString,NSData,NSDate,NSArray,NSDictionary 18 //数组、字典写入的文件叫做属性文件,可以使用xcode进行编辑 19 int main(int argc, charchar * argv[]) { 20 @autoreleasepool { 21 22 //1.-------------------字符串读写文件 23 NSString *str = @"无线互联"; 24 NSString *homePath = NSHomeDirectory(); 25 NSString *filePath = [homePath stringByAppendingPathComponent:@"Documents/file.text"]; 26 //现在有这样的场景,第一次把字符串写入到文件中,当我们修改字符串之后,再次写入的时候,但是可能会写入失败 27 //但是之前的内容也有可能丢失,因为每次在写入新的内容的时候,会剪切之前的内容,所以这里就有可能新的没有写 28 //成功,旧的文件也丢失了 29 //所以这时候atomically参数: 30 //YES:会将新内容先写入到一个缓存文件中,如果写入缓存成功之后,这时候就将这个缓存文件替换旧文件,这样就很安全了 31 BOOL sucess = [str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil]; 32 if(sucess){ 33 //写入成功 34 }else{ 35 //写入失败 36 } 37 //读取文件内容到字符串中 38 //类方法 39 NSString *str1 = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; 40 //构造方法 41 //str1 = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; 42 NSLog(@"%@",str1); 43 44 45 //2.--------------------NSData读写 46 //创建NSData的同时读取文件中的内容 47 NSData *data =http://www.mamicode.com/ [[NSData alloc] initWithContentsOfFile:filePath]; 48 //NSData转化成NSString 49 NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 50 NSLog(@"%@",s); 51 52 //写文件 53 BOOL sucess1 = [data writeToFile:filePath atomically:YES]; 54 if(sucess1){ 55 //写入成功 56 }else{ 57 //写入失败 58 } 59 60 61 //3.--------------------NSArray读写文件 62 NSArray *array = @[@"zhangsan",@"lisi"]; 63 //属性文件一般后缀名为.plist 64 NSString *filePaths = [homePath stringByAppendingPathComponent:@"Documents/array.plist"]; 65 BOOL sucess2 = [array writeToFile:filePaths atomically:YES]; 66 if(sucess2){ 67 //写入成功 68 }else{ 69 //写入失败 70 } 71 //读文件 72 NSArray *arrays = [[NSArray alloc] initWithContentsOfFile:filePath]; 73 NSLog(@"%@",arrays); 74 75 76 //4.---------------------NSDictionary读写文件 77 NSDictionary *dic = @{@"zhang":@"zhangsan",@"li":@"lisi"}; 78 BOOL sucess3 = [dic writeToFile:filePath atomically:YES]; 79 if(sucess3){ 80 //写入成功 81 }else{ 82 //写入失败 83 } 84 85 //读文件 86 dic = [[NSDictionary alloc] initWithContentsOfFile:filePath]; 87 NSLog(@"%@",dic); 88 89 90 return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 91 } 92 }
这个类就和Java中的FileInputStream/FileOutputStream类似了,其实我们在之前看到归档和解档操作的时候,那就是相当于写文件和读文件操作了。
1、字符串直接写入文件
1 //1.-------------------字符串读写文件 2 NSString *str = @"无线互联"; 3 NSString *homePath = NSHomeDirectory(); 4 NSString *filePath = [homePath stringByAppendingPathComponent:@"Documents/file.text"]; 5 //现在有这样的场景,第一次把字符串写入到文件中,当我们修改字符串之后,再次写入的时候,但是可能会写入失败 6 //但是之前的内容也有可能丢失,因为每次在写入新的内容的时候,会剪切之前的内容,所以这里就有可能新的没有写 7 //成功,旧的文件也丢失了 8 //所以这时候atomically参数: 9 //YES:会将新内容先写入到一个缓存文件中,如果写入缓存成功之后,这时候就将这个缓存文件替换旧文件,这样就很安全了 10 BOOL sucess = [str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil]; 11 if(sucess){ 12 //写入成功 13 }else{ 14 //写入失败 15 } 16 //读取文件内容到字符串中 17 //类方法 18 NSString *str1 = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; 19 //构造方法 20 //str1 = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; 21 NSLog(@"%@",str1);
我们使用拼接的方式创建Documents目录中的file.text文件,然后将字符串内容写入到其中。
writeToFile方法进行写入:
其实OC中的各种数据结构都有这个方法的:NSString,NSData,NSArray,NSSet,NSDirctionary等。
这里有两点要注意的:
1)数组只能将如下类型写入文件,如果包含其他对象,将写入失败:NSNumber,NSString,NSData,NSDate,NSArray,NSDictionary
数组、字典写入的文件叫做属性文件,可以使用xcode进行编辑。