沙盒组成
注意:如果创建的.txt等文件中没有任何数据,将不会显示
Document:存储用户数据,需要备份的信息。
Library/Caches:存储缓存文件,程序专用的支持文件
Library/Preferences:存储应用程序的偏好设置文件
.app :程序包(IOS8时,app不存储在沙盒中,有单独的文件夹存储所有程序的app包)
tem:存储临时文件。比如:下载的zip包,解压后的再删除。
---------------------------------------------------------------
获取沙盒目录路径的方法
NSHomeDirectory---------------->沙盒主路径
NSDocumentDirectory------------>Documents文件夹
NSLibraryDirectory---------------->Library文件夹
NSCachesDirectory---------------->Caches文件夹
NSTemporaryDirectory------------>tmp文件夹
----------------------------------------------------------------
简单示例-----向document中添加字符串文件并取出
1 // 1.字符串文件的存储路径 2 // 获取所有的documents文件夹---如果里边的三个量填写错误,会造成路径为空 3 NSArray *docArr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 4 // 将最后的document文件夹路径作为文件的存储目录 5 NSString *docPath = docArr.lastObject; 6 // 构造字符串文件的存储路径 7 NSString *strPath = [docPath stringByAppendingPathComponent:@"text.txt"]; 8 // 构造字符串对象 9 NSString *str = @"this is a test"; 10 // 通过将writeToFile:atomitically:encoding:error:方法发送给字符串对象完成字符串存储到文件内的功能 NSUTF8StringEncoding编码方式能输入汉字 11 [str writeToFile:strPath atomically:YES encoding:NSUTF8StringEncoding error:nil]; 12 // 从沙盒中取出字符串 13 NSString *strOut = [NSString stringWithContentsOfFile:strPath encoding:NSUTF8StringEncoding error:nil]; 14 NSLog(@"%@",strOut);
同理可以将数组,字典,二进制对象写入文件,完成文件的永久存储
1 // 2.数组对象写入文件 2 // 构建数组plist文件的存储路径 3 NSString *arrPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingString:@"arr.txt"]; 4 // 构建数组对象 5 NSArray *arr = @[@"哈哈",@"呵呵",@"哈呵呵",@"呵哈哈"]; 6 // 将数组添加到文件--为什么写YES?查API 7 [arr writeToFile:arrPath atomically:YES]; 8 9 // 3.字典对象写入文件 10 // 构造字典plist文件的存储路径 11 NSString *dicPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingString:@"/dic.txt"]; 12 // 创建字典对象 13 NSDictionary *dic = @{@"name": @"张三",@"age": @"10",@"sex": @"男"}; 14 // 将字典对象存储到文件内 15 [dic writeToFile:dicPath atomically:YES]; 16 17 // 4.二进制对象写入文件 18 NSString *dataPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingString:@"/data.png"]; 19 // 创建data对象 20 UIImage *image = [UIImage imageNamed:@"fashi1.png"]; 21 // 将图片转化成二进制数据 22 NSData *data = UIImagePNGRepresentation(image); 23 [data writeToFile:dataPath atomically:YES];
在添加文件时有时候需要中间添加文件夹,NSFileManager类可以帮助我们完成这项功能
1 // 通过NSFileManager可以实现文件夹的添加 2 // defaultManager表示是一个单例 3 NSFileManager *manager = [NSFileManager defaultManager]; 4 // 构造文件存储路径创建了三个文件夹,必须向文件夹中添加数据才能显示 5 // NSString *dirPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingString:@"/aa/bb/dic.txt"]; 6 NSString *dirPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingString:@"/aa/bb"]; 7 // 创建文件路径,当withIntermediateDirectories为YES时创建中间文件夹,NO是不创建中间文件夹 8 [manager createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:nil]; 9 // 添加了两个文件夹,然后再在bb文件夹中添加文件 10 NSString *str1Path = [dirPath stringByAppendingString:@"/haha.txt"]; 11 // 向文件中添加内容,进行文件创建,不添加内容没有文件显示 12 NSString *a = @"你好吗,吃了吗?"; 13 [a writeToFile:str1Path atomically:YES encoding:NSUTF8StringEncoding error:nil];
文件的拷贝和移动就没有什么意思了。。。
拷贝和移动原理:如果从A文件夹中的a文件内容拷贝到到B文件,则需要先在B文件先手动创建一个承接
a文件的b文件,然后再将a文件的内容拷贝到b文件中。移动原理类似,将a文件里边的内容拷贝到b文件中
,然后再将a文件移除,很没意思。。。
1 // 创建NSFileManager对象 2 NSFileManager *manager = [NSFileManager defaultManager]; 3 // 获取开始发出文件的路径,并准备创建一个start文件夹 4 NSString *startPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingString:@"/start"]; 5 // 用manager方法创建文件夹 6 [manager createDirectoryAtPath:startPath withIntermediateDirectories:YES attributes:nil error:nil]; 7 // 在文件夹中创建start.txt文件 8 NSString *sourcePath = [startPath stringByAppendingString:@"/start.txt"]; 9 // 文件内输入内容输入内容 10 NSString *str = @"mini"; 11 // 写入内容 12 [str writeToFile:sourcePath atomically:YES encoding:NSUTF8StringEncoding error:nil]; 13 // 获取最后接收文件的路径,并准备创建一个end文件夹来接收文件 14 NSString *endPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingString:@"/end"]; 15 // 创建文件夹 16 [manager createDirectoryAtPath:endPath withIntermediateDirectories:YES attributes:nil error:nil]; 17 // 在end文件夹中创建一个空的end.txt文件,用来接收start.txt的内容,并获取文件路径 18 NSString *destPath = [endPath stringByAppendingString:@"/end.txt"]; 19 NSLog(@"%@",sourcePath); 20 // 准备接收错误信息 21 NSError *error = nil; 22 // 完成拷贝过程 23 [manager copyItemAtPath:sourcePath toPath:destPath error:&error]; 24 // 完成移动过程 25 [manager moveItemAtPath:sourcePath toPath:destPath error:&error];
复杂对象写入文件持久保存
复杂对象是没有writeToFile方法的,所有不能直接写入文件,解决这一问题的思路是:
将复杂的对象转化成简单对象,然后调用简单对象的writeToFile方法实现持久化。
NSKeyedArchiver:归档类,主要功能是将对象转化成二进制数据(NSData)。
NSKeyedUnarchiver:反归档类,主要功能是将二进制数据(NSData)还原成对象。
被归档的对象,必须遵循NSCoding协议,实现里面的方法。
1 #import <Foundation/Foundation.h> 2 3 //要归档的对象,必须遵循NSCoding协议 4 @interface User : NSObject<NSCoding> 5 6 @property (nonatomic,copy) NSString *name; 7 @property (nonatomic,copy) NSString *pwd; 8 @property (nonatomic,assign) int status; 9 10 @end 11 12 #import "User.h" 13 14 @implementation User 15 16 17 //代理方法,在归档方法中作用于_delegate实例变量,方法对外提供的赋值的接口 18 - (void)encodeWithCoder:(NSCoder *)aCoder { 19 20 [aCoder encodeObject:self.name forKey:@"name"]; 21 [aCoder encodeObject:self.pwd forKey:@"pwd"]; 22 [aCoder encodeInt:self.status forKey:@"status"]; 23 24 } 25 26 //反归档时调用此方法,将数据重新赋给对象 27 - (id)initWithCoder:(NSCoder *)aDecoder { 28 29 self = [super init]; 30 if (self) { 31 self.name = [aDecoder decodeObjectForKey:@"name"]; 32 self.pwd = [aDecoder decodeObjectForKey:@"pwd"]; 33 self.status = [aDecoder decodeIntForKey:@"status"]; 34 } 35 return self; 36 } 37 38 - (void)dealloc { 39 [_name release]; 40 [_pwd release]; 41 [super dealloc]; 42 } 43 44 @end
归档与反归档的内部实现细节
1 // 归档的基本实现步骤 2 // 1.创建空MutableData对象用于接收归档数据 3 NSMutableData *mulData = [NSMutableData data]; 4 // 2.利用空的mulData创建一个归档类对象,用于接收数据 5 NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:mulData]; 6 // 3.利用归档方法进行归档,并对归档数据做标记 7 [archiver encodeObject:user forKey:@"user"]; 8 // 结束归档 9 [archiver finishEncoding]; 10 NSLog(@"%@",mulData); 11 12 // 反归档步骤 13 // 1.利用存有数据的mulData创建反归档对象unarchiver 14 NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:mulData]; 15 // 2.利用反归档方法通过标记将mulData中的数据写入receiveUser 16 User *receiveUser = [unarchiver decodeObjectForKey:@"user"]; 17 // 3.输出数据 18 NSLog(@"%@ %@",receiveUser.name,receiveUser.pwd);
归档与反归档平常使用方法---直接将对象归档到文件中
// 归档与反归档的平常使用方法:直接将数据归档到文件中 User *user = [[User alloc] init]; user.name = @"张三"; user.pwd = @"13412"; // 获取文件路径,并创建一个archiver文件 NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingString:@"/archiver.txt"]; // 直接将将对象归档到文件中,直接使用类方法 [NSKeyedArchiver archiveRootObject:user toFile:filePath]; // 直接使用反归档类方法将文件取出来 User *testUser = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; // 输出 NSLog(@"%@ %@",testUser.name,testUser.pwd);