一. iOS沙盒存储结构
沙盒目录是一种数据安全策略,设计原理是只允许自己的应用访问目录,而不允许其他应用访问,只有特定的API共享特定的数据。目录结构如下:
|---------------Documents: 用于用户生成的大文件或需要非常频繁更新的数据,能够进行iTunes或iCloud备份。(游戏进度,写的日记什么的)
| /----------List.sqlite3
|---------------Library:
| /----------Caches 用于存放网络获取的数据。(音乐图片缓存)(不会iCloud备份)
| /----------Preferences 用户偏好设置(iCloud备份)NSUserDefault
|---------------tmp: 临时存储。(手机存储不够系统会去删除里面的东西)
|---------------YourApp.app: bundle包。(程序包资源)
目录获取方式:
1.Mac模拟器沙盒总路径:
NSString *homePath = NSHomeDirectory();
输出路径:
/Users/jiling/Library/Developer/CoreSimulator/Devices/47450F88-22B6-41FD-8CB0-09FFEA47C551/data/Containers/Data/Application/1B4DD145-0086-42F0-8B6D-1ABBACC2F0CF
2.Documents路径:
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
输出路径:
/Users/jiling/Library/Developer/CoreSimulator/Devices/47450F88-22B6-41FD-8CB0-09FFEA47C551/data/Containers/Data/Application/1B4DD145-0086-42F0-8B6D-1ABBACC2F0CF/Documents
3.Library/Caches路径:
NSString *libCachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
输出路径:
/Users/jiling/Library/Developer/CoreSimulator/Devices/47450F88-22B6-41FD-8CB0-09FFEA47C551/data/Containers/Data/Application/1B4DD145-0086-42F0-8B6D-1ABBACC2F0CF/Library/Caches
(Library/Preferences 由NSUserDefaults管理)
4.tmp路径:
NSString *tmpPath = NSTemporaryDirectory();
输出路径:
/Users/jiling/Library/Developer/CoreSimulator/Devices/47450F88-22B6-41FD-8CB0-09FFEA47C551/data/Containers/Data/Application/1B4DD145-0086-42F0-8B6D-1ABBACC2F0CF/tmp/
5.bundle包路径:
NSString *bundlePath = [NSBundle mainBundle].bundlePath;
输出路径:
/Users/jiling/Library/Developer/CoreSimulator/Devices/47450F88-22B6-41FD-8CB0-09FFEA47C551/data/Containers/Bundle/Application/1E871CFC-2F8A-4032-ADB2-F1C797AF8D11/HelloWorld.app
二. NSFileManager 和 NSFileHandle
就像类名字显示的,Manger用于管理文件,创建文件,删除文件,Handle用于处理文件,改变文件的内容。
1.NSFileManager--文件创建
//文件路径
NSString *tmpPath = NSTemporaryDirectory();
NSString *fileName = @"hello.txt";
tmpPath = [tmpPath stringByAppendingPathComponent:fileName]; //这个方法会监测是否用加'/',用来合成path
//创建文件
NSFileManager *fileManager = [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:tmpPath]){ //判断下文件是否已经存在
BOOL flag = [fileManager createFileAtPath:tmpPath contents:nil attributes:nil];
if(flag){
NSLog(@"文件创建成功");
}else{
NSLog(@"文件创建失败");
}
}
2.NSFileManager--创建目录
//目录路径
NSString *tmpPath = NSTemporaryDirectory();
NSString *directorName = @"hello";
NSString *path = [tmpPath stringByAppendingPathComponent:directorName];
//创建目录
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL flag = [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
if(flag){
NSLog(@"创建目录成功");
}else{
NSLog(@"创建目录失败");
}
3.NSFileManager--删除文件和目录
NSFileManager *fileManager = [NSFileManager defaultManager];
//目录路径
NSString *tmpPath = NSTemporaryDirectory();
NSString *directorName = @"test1";
NSString *path = [tmpPath stringByAppendingPathComponent:directorName];
//删除文件
NSArray *array = [fileManager contentsOfDirectoryAtPath:path error:nil];
for(NSString * str in array){ //循环删除test2下所有文件及目录
NSString *filePath = [path stringByAppendingPathComponent:str];
BOOL flag = [fileManager removeItemAtPath:filePath error:nil];
if(flag){
NSLog(@"删除成功");
}else{
NSLog(@"删除失败");
}
}
4.NSFileManager--其它方法
//将一个文件复制到另一个文件
[fileManager copyItemAtPath:path1 toPath:path2 error:nil];
//将一个文件移动到另一个文件
[fileManager moveItemAtPath:path1 toPath:path2 error:nil];
//获取文件里面的内容
NSData * readData=[fileManager contentsAtPath:path]
5.NSFileHandle--文件写入
//文件路径
NSString *tmpPath = NSTemporaryDirectory();
NSString *fileName = @"hello.txt";
NSString *path = [tmpPath stringByAppendingPathComponent:fileName];
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:path]; //根据路径初始化handle
NSString *str = @"hello"; //要写入的内容
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
[fileHandle writeData:data]; //写数据
[fileHandle closeFile]; //用完之后一定要关闭文件
在已有内容,移动光标位置输入:
//文件路径
NSString *tmpPath = NSTemporaryDirectory();
NSString *fileName = @"hello.txt";
NSString *path = [tmpPath stringByAppendingPathComponent:fileName];
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:path]; //根据路径初始化handle
NSString *str = @" world"; //要写入的内容
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
[fileHandle seekToEndOfFile]; //将光标移到文件结尾
[fileHandle writeData:data]; //写数据
[fileHandle closeFile]; //用完之后一定要关闭文件
6.NSFileHandle--文件读入
//文件路径
NSString *tmpPath = NSTemporaryDirectory();
NSString *fileName = @"hello.txt";
NSString *path = [tmpPath stringByAppendingPathComponent:fileName];
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:path]; //根据路径初始化handle
NSData *data1 = [fileHandle readDataToEndOfFile]; //读取到文件的末尾
[fileHandle availableData]; //查询该文件可用数据的个数
NSData * data3 = [fileHandle readDataOfLength:3]; //读取指定长度的文件
[fileHandle closeFile];
三. iOS数据存储常用方式
1.plist文件读写
用于存储常用OC数据类型,要实现writeToFile方法的类型。
写入数据-NSArray:
//文件路径
NSString *tmpPath = NSTemporaryDirectory();
NSString *fileName = @"str1.plist";
NSString *path = [tmpPath stringByAppendingPathComponent:fileName];
//写入数据
NSArray *array = @[@"a",@"b",@"c"];
[array writeToFile:path atomically:YES]; //如果没有这个文件会创建文件,如果已经存在,会覆盖文件
查看下结果:
写入数据-NSDictionary:
//文件路径
NSString *tmpPath = NSTemporaryDirectory();
NSString *fileName = @"str.plist";
NSString *path = [tmpPath stringByAppendingPathComponent:fileName];
//写入数据
NSDictionary *dic = @{@"aa":@"1",@"bb":@"2",@"cc":@"3"};
[dic writeToFile:path atomically:YES];
查看下结果:
读plist数据,例:
NSArray *array = [NSArray arrayWithContentsOfFile:filePath];
2.Preferences偏好数据
每个应用都有一个 NSUserDefault 实例,用来存取偏好设置,例如:用户名,字体,登录方式状态等。不需要关心文件名称,键值对存取。实际存储形式为plist,所以依然只能存plist支持的类型,NSData, NSString, NSNumber, NSDate, NSArray, NSDictionary。不支持的类型,如图片,可以先转成NSData,再存。
NSUserDefault也为我们提供了一些定制好的方法,如下:
- setBool:forKey:
- setFloat:forKey:
- setInteger:forKey:
- setDouble:forKey:
- setURL:forKey:
- setValue:forKey:
存入:
//获取设置单例
NSUserDefaults *UserDefaults = [NSUserDefaults standardUserDefaults];
// 1、写入---系统会去存储数据
[UserDefaults setBool:NO forKey:@"isLogined"];
// 2、强制写入---当需要立即存储的时候
[UserDefaults synchronize];
获取:
//获取设置单例
NSUserDefaults *UserDefaults = [NSUserDefaults standardUserDefaults];
BOOL isLogined = [UserDefaults objectForKey:@"isLogined"];
注:1.有关NSUserDefaults域的知识,总结好会加上来。
2.但是setBool遇到问题了,就是set不成功的问题,反正可以用其它的代替...
3.NSKeyedArchiver归档
相对于plist,NSKyeyedArchiver可以存储自定义模型。相对于SQLite,NSKyeyedArchiver不适合存储大批量数据,在读取某一数据时,要把文件中所有数据都读取,再寻找,如果数据量过大,性能堪忧。
注:要归档的模型,必须遵循NSCoding协议,然后再模型中必须实现两个方法,
归档:encodeWithCoder
解档:initWithCoder
如果父类也遵循NSCoding,那么注意这两句的添加,[super encodeWithCoder:encode]; self = [super initWithCoder:decoder];
使用例子:
4.SQLite3
SQLite是一款轻型的嵌入式数据库,占用的资源低,速度快。
传送门:(后续)
5.Core Data
Core Data是一个框架,它使得开发者可以吧数据当成对象来操作。
|-------------------------------| |------------------| |--------------------------------|
| 持久化存储协调器 | |托管对象模型| | 托管对象context |
|-------------------------------| |------------------| |--------------------------------|
| 持久化存储区 | | 对象图 | | |
| 数据表中的某行 <=======================> 托管对象 |
|__________________| |___________| |___________________|
1.1 持久化存储协调器 persistent store coordinator
NSPersistentStore : 用于创建持久化存储区
NSPersistentStoreCoordinator : 用于创建持久化存储协调器
1.2 托管对象模型(对象图)
NSManagedObjectModel : 用于创建托管对象模型
1.3托管对象上下文
NSManagedObjectContext : 创建托管对象上下文