一. 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];   //如果没有这个文件会创建文件,如果已经存在,会覆盖文件

查看下结果:

ios 保存_沙盒

写入数据-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];

查看下结果:

ios 保存_文件_02

 读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 : 创建托管对象上下文