iOS应用数据存储的常用方式:


 1.XML 属性列表     ( plist 归档)


 2.NSUserDefaults  ( 偏好设置 )


 3.NSKeyedArchiver   归档(加密形式)


 4.SQLite3     (嵌入式数据库)


 5.Core Data    (面向对象方式的嵌入式数据库)


 


 


一.应用沙盒


 


1.iOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒


  说明:


    a.每个应用程序都有自己的存储空间


    b.应用程序无法翻过自己的围墙去访问别的存储空间的内容


    c.应用程序请求的数据都要通过权限检测,假如不符合条件的话,不会被放行。


 


2.mac下查看沙盒路径


  step1. 显示Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles -bool true


  step2.进入如下路径 /Users/username/Library/Application Support/iPhone Simulator/,即可找到各个程序的应用沙盒


 


3.沙盒目录结构


     默认情况下,每个程序的沙盒含有3个文件夹:Documents, Library 和 tmp:



    

ios应用文件夹结构 iphone应用文件夹 管理_ios应用文件夹结构


会备份该目录

会备份该目录

不会备份该目录。

不会备份该目录

 

4.获取目录路径代码:


//获取沙盒路径
    NSString *home = NSHomeDirectory();
    
    //1.获取Document路径
    //1.1通过文件名获取,因为ios以后的新版本可能修改目录名,不建议使用
    NSString *documentPath1 = [home stringByAppendingPathComponent:@"Documents"];
    //1.2通过系统方法获取,建议使用
    NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath2 = [array objectAtIndex:0];
    
    //2.获取Library/Cache目录,获取方式同Document,下面是系统方法
    NSArray *cache = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cachePath = [cache objectAtIndex:0];
    
    //3.获取Library/Preferences也可食用1.1的方式获取,但因为是保存setting设置,一般通过NSUserDefaults直接存储
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:@"myname" forKey:@"username"];
    
    //4.获取tmp目录
    NSString *tmpPath = NSTemporaryDirectory();


 

如何在沙盒中操作文件夹和文件,系统提供了

 

二.文件存储

1.XML属性列表(plist归档)


dataWithContentsOfFile方法读取plist文件中的信息并实例化对象


NSString *tmpPath = NSTemporaryDirectory();
    NSString *path = [tmpPath stringByAppendingPathComponent:@"test.plist"];
    
    // 将数据封装成字典
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    [dict setObject:@"jason" forKey:@"name"];
    [dict writeToFile:path atomically:YES];
    
    // 读取plist的内容,实例化NSDictionary
    NSDictionary *dictPlist = [NSDictionary dictionaryWithContentsOfFile:path];
    NSLog(@"name:%@", [dictPlist objectForKey:@"name"]);


 

2.NSUserDefaults(偏好设置)


   使用set方法保存不同类型的对象,使用xxxForKey方法获取值


//偏好设置
    NSUserDefaults *dft = [NSUserDefaults standardUserDefaults];
    [dft setObject:@"jason" forKey:@"username"];
    [dft setFloat:1.77f forKey:@"high"];
    [dft setBool:YES forKey:@"auto_logon"];
    
    //读取偏好设置
    NSUserDefaults *dft2 = [NSUserDefaults standardUserDefaults];
    NSString *name = [dft2 objectForKey:@"username"];
    float h = [dft2 floatForKey:@"high"];
    BOOL al = [dft2 boolForKey:@"auto_logon"];
    NSLog(@"%@--%f--%hhd",name,h,al);


  自动在Library/Preferences/生成项目名开头的plist文件

  

ios应用文件夹结构 iphone应用文件夹 管理_反归档_02

 

3.NSKeyedArchiver  归档(加密形式)

  机制类似于java的对象序列化,归档是指将对象保存到文件,反归档(读档)是指将文件内容解析成对象

NSString、NSDictionary、NSArray、NSData、NSNumber等类型,可以直接用NSKeyedArchiver进行归档和反归档

  3.2 任何遵守了NSCoding协议的对象,都可以进行归档和反归档

NSCoding协议需要实现两个方法:
    - (void)encodeWithCoder:(NSCoder *)encoder //将对象归档的时候会调用(将对象写入文件之前会调用),用来说明哪些属性需要归档,怎样归档

id)initWithCoder:(NSCoder *)decoder //当从文件中反归档对象时调用,用来说明哪些属性需要反归档,怎样反归档

super的encodeWithCoder:和initWithCoder:方法

  3.4代码实例:

    3.4.1 对象类:Person和子类Man


//  Person.h
#import <Foundation/Foundation.h>

@interface Person : NSObject<NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) double height;
@end

//  Person.m

#import "Person.h"

@implementation Person

//归档时调用
- (void)encodeWithCoder:(NSCoder *)coder
{
    [coder encodeObject:_name forKey:@"name"];
    [coder encodeInt:_age forKey:@"age"];
    [coder encodeDouble:_height forKey:@"height"];
}

//反归档时调用调用的初始化方法
-(id)initWithCoder:(NSCoder *)deCode
{
    if (self = [super init]) {
        _name   = [deCode decodeObjectForKey:@"name"];
        _age    = [deCode decodeIntForKey:@"age"];
        _height = [deCode decodeDoubleForKey:@"height"];
    }
    return self;
}

@end



//  Man.h继承自Person
#import "Person.h"

@interface Man : Person
@property (nonatomic, copy) NSString *sex;
@end

//  Man.m
#import "Man.h"

@implementation Man

//归档时调用
-(void)encodeWithCoder:(NSCoder *)coder
{
    //首先调用父类的归档方法
    [super encodeWithCoder:coder];
    [coder encodeObject:_sex forKey:@"sex"];
}

//反归档时调用的初始化方法
-(id)initWithCoder:(NSCoder *)deCode
{
    if (self = [super initWithCoder:deCode]) {
        _sex = [deCode decodeObjectForKey:@"sex"];
    }
    return  self;
}

@end


 

    3.4.1 归档和反归档的实现方法


NSString *tmpPath = NSTemporaryDirectory();
    NSString *path1 = [tmpPath stringByAppendingPathComponent:@"person.data"];
    NSString *path2 = [tmpPath stringByAppendingPathComponent:@"man.data"];
    
    Person *p = [[Person alloc]init];
    p.name = @"a";
    p.age = 11;
    p.height = 1.70f;
    
    Man *m = [[Man alloc]init];
    m.name = @"b";
    m.age = 12;
    m.height = 1.77f;
    m.sex = @"male";
    
    //归档
    [NSKeyedArchiver archiveRootObject:p toFile:path1];
    [NSKeyedArchiver archiveRootObject:m toFile:path2];
    
    //反归档
    Person *p2 = [NSKeyedUnarchiver unarchiveObjectWithFile:path1];
    Man *m2 = [NSKeyedUnarchiver unarchiveObjectWithFile:path2];
    NSLog(@"%@--%d--%f",p2.name,p2.age,p2.height);
    NSLog(@"%@--%d--%f---%@",m2.name,m2.age,m2.height,m2.sex);


 

Core Data

  都是对数据做操作,CoreData只是在SQLite3的基础上做了一层面向对象的封装,类似于Hibernate,暂不总结,后续会新写文章总结

 

 

三.NSFileManager


 

创建文件夹:

 

//创建文件夹
-(void *)createDir{
    NSString *documentsPath =[self dirDoc];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
    // 创建目录
    BOOL res=[fileManager createDirectoryAtPath:testDirectory withIntermediateDirectories:YES attributes:nil error:nil];
    if (res) {
        NSLog(@"文件夹创建成功");
    }else
        NSLog(@"文件夹创建失败");
 }


 

创建文件

 

//创建文件
-(void *)createFile{
    NSString *documentsPath =[self dirDoc];
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];
    BOOL res=[fileManager createFileAtPath:testPath contents:nil attributes:nil];
    if (res) {
        NSLog(@"文件创建成功: %@" ,testPath);
    }else
        NSLog(@"文件创建失败");
}

写数据到文件:

 

 

//写文件
-(void)writeFile{
    NSString *documentsPath =[self dirDoc];
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
    NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];
    NSString *content=@"测试写入内容!";
    BOOL res=[content writeToFile:testPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
    if (res) {
        NSLog(@"文件写入成功");
    }else
        NSLog(@"文件写入失败");
}

 

读文件数据:

 

 

//读文件
-(void)readFile{
    NSString *documentsPath =[self dirDoc];
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
    NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];
//    NSData *data = [NSData dataWithContentsOfFile:testPath];
//    NSLog(@"文件读取成功: %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    NSString *content=[NSString stringWithContentsOfFile:testPath encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"文件读取成功: %@",content);
}

 

文件属性:

 

 

//文件属性
-(void)fileAttriutes{
    NSString *documentsPath =[self dirDoc];
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];
    NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:testPath error:nil];   
    NSArray *keys;
    id key, value;
    keys = [fileAttributes allKeys];
    int count = [keys count];
    for (int i = 0; i < count; i++)
    {
        key = [keys objectAtIndex: i];
        value = [fileAttributes objectForKey: key];
        NSLog (@"Key: %@ for value: %@", key, value);
    }
}

 

 

删除文件:

  

//删除文件
-(void)deleteFile{
    NSString *documentsPath =[self dirDoc];
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];   
    BOOL res=[fileManager removeItemAtPath:testPath error:nil];
    if (res) {
        NSLog(@"文件删除成功");
    }else
        NSLog(@"文件删除失败");   
    NSLog(@"文件是否存在: %@",[fileManager isExecutableFileAtPath:testPath]?@"YES":@"NO");
}

遍历子文件夹:

NSString *home = NSHomeDirectory();
NSFileManager *fileManage = [NSFileManagerdefaultManager];
NSArray *file = [fileManage subpathsOfDirectoryAtPath: home error:nil];
NSLog(@"%@",file);
NSArray *files = [fileManage subpathsAtPath: home ];
NSLog(@"%@",files);