iOS数据持久化(一)

一、什么是数据持久化

数据持久化及数据的永久存储,将数据保存在硬盘中,程序关闭,内存释放后,重新打开程序,可以继续访问之前保存的数据。

二、数据持久化方式

常见的数据持久化方式有以下几项:

沙盒

preference

归档 / 反归档

SQLite

CoreData

这篇只讲沙盒,preference,归档/反归档。

1.沙盒

沙盒是系统为每一个应用程序生成的一个特定文件夹   文件夹的名字由十六进制数据组成,每一个应用程序的沙盒文件名都是不一样的,是由系统随机生成的。

    //获取沙盒主目录
    NSString *path = NSHomeDirectory();
    NSLog(@"%@",path);

沙盒下每个文件夹的路径及作用

//Documents  存放的一些比较重要的文件,但是存入Documents中的文件不能过大
    //如何获取Documents文件目录
    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSLog(@"%@",documentsPath);
    //用firstobject取值是因为该方法一开始使用mac端OS X开发,对于PC端用户可以有多个用户,所以可以取到很多user的路径,但是该方法现在用于手机开发,手机端只有一个用户,所以获得的用户只有一个,lastobject也是可以的。

    //Library:是一个资源库,存储一些不太重要的数据,相对比较大一些,里边有两个子文件夹;
    NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)firstObject];
    //Caches:缓存文件,图片缓存,音频,视频。网页资源。应用程序清除缓存,就是清除该文件夹
    NSString *cachesPath  = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)firstObject];
    //Preferences:系统偏好设置,用户对应程序的设置,比如用户名和用户密码,preference路径无法找到,通过NSUserDefaults

    //temp:存放临时文件,比如下载的压缩包zip,解压后理解把压缩包删除
    NSString *tempPath = NSTemporaryDirectory();
    NSLog(@"%@",tempPath);
    //bundle:ios8之前,包和沙河在同一个目录下,之后.app单独存储到一个独立的文件目录下。 .app 文件 readOnly。从appStore下载下来的是这个包,程序上传的时候也是这个包
    NSString *bundlepath = [[NSBundle mainBundle] bundlePath];
    NSLog(@"%@",bundlepath);
    // NSSearchPathDirectory 这个类是用来查找文件目录的
    //第一个参数:文件名称
    //第二个参数,确定搜索域
    //第三个参数:确定相对路径还是绝对路径。YES绝对,NO相对

文件相关操作

/**
 *  文件删除
 */
- (void)deleteFile {
    NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];

     NSString *imagePath = [cachesPath stringByAppendingPathComponent:@"iamge"];
    NSLog(@"%@",imagePath);
    //创建文件管理者
    NSFileManager *fileManager =  [NSFileManager defaultManager];
    //判断文件是否存在
    BOOL isExist = [fileManager fileExistsAtPath:imagePath];
    if (!isExist) {
        BOOL isSuccess = [fileManager createDirectoryAtPath:imagePath withIntermediateDirectories:YES attributes:nil error:nil];
        NSLog(@"%@",isSuccess ? @"创建成功" : @"创建失败");
    }
    //删除文件
    if ([fileManager fileExistsAtPath:imagePath]) {
        BOOL isSucess = [fileManager removeItemAtPath:imagePath error:nil];
        NSLog(@"%@",isSucess ? @"删除成功" : @"删除失败");
    }
}
/**
 *  移动
 */
- (void)moveFile {
    NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];

    NSString *imagePath = [cachesPath stringByAppendingPathComponent:@"iamge"];
    NSLog(@"%@",imagePath);
    //创建文件管理者
    NSFileManager *fileManager =  [NSFileManager defaultManager];
    //判断文件是否存在
    BOOL isExist = [fileManager fileExistsAtPath:imagePath];
    if (!isExist) {
        BOOL isSuccess = [fileManager createDirectoryAtPath:imagePath withIntermediateDirectories:YES attributes:nil error:nil];
        NSLog(@"%@",isSuccess ? @"创建成功" : @"创建失败");
    }
    //删除文件
    //    if ([fileManager fileExistsAtPath:imagePath]) {
    //        BOOL isSucess = [fileManager removeItemAtPath:imagePath error:nil];
    //        NSLog(@"%@",isSucess ? @"删除成功" : @"删除失败");
    //    }
    //拷贝文件
    //    把包中的plist文件拷贝到image文件夹下
    NSString *plistInBundlePath = [[NSBundle mainBundle] pathForResource:@"NB.plist" ofType:nil];

    NSString *nBPath = [imagePath stringByAppendingPathComponent:@"NB.plist"];
    // 拷贝,
    if (![fileManager fileExistsAtPath:nBPath]) {
        BOOL isSuccess = [fileManager copyItemAtPath:plistInBundlePath toPath:nBPath error:nil];
        NSLog(@"%@",isSuccess ? @"拷贝成功" : @"拷贝失败");
    }

    NSString *toPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject];
    BOOL isSuccess = [fileManager moveItemAtPath:nBPath toPath:[toPath stringByAppendingPathComponent:@"NB.plist"] error:nil];
    NSLog(@"%@",isSuccess ? @"移动成功" : @"移动失败");

}
//字符串写入文件
- (void)writeToFile {
    //简单对象写入文件:字符串,数组,字典,二进制流 只有这些简单对象支持文件的写入
    //如果要写入的文件数据时数组,字典,必须要保证数组,字典中的数据 也是简单对象(如果是复杂对象,请参照后边的归档,反归档)
    //将字符串写入Documents文件夹下
    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject];
    NSString *toPath = [documentsPath stringByAppendingPathComponent:@"string.txt"];
    NSString *string = @"string-string-string-";
    //第一个参数,要写入的文件路径,如果不存在文件,会自动创建    第二个参数,原子性,判断是否需要生成辅助文件,保护在多线程下安全    第三个参数,编码格式    第四个参数,错误信息
    NSError *error = nil;
    BOOL isSuccess = [string writeToFile:toPath atomically:YES encoding:NSUTF8StringEncoding error:&error];
    NSLog(@"%@",isSuccess ? @"写入成功" : @"写入失败");

    NSString *str = [NSString stringWithContentsOfFile:toPath encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"%@",str);
}
//数组写入文件
- (void)writeArray {

    NSString *str = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)firstObject];
    NSString *toPath = [str stringByAppendingPathComponent:@"array.txt"];
    NSArray *array = @[@"123",@"123"];
    BOOL isSuccess = [array writeToFile:toPath atomically:YES];
    NSLog(@"%@",isSuccess ? @"写入成功" : @"写入失败");

    NSArray *arr = [NSArray arrayWithContentsOfFile:toPath];
    NSLog(@"%@",arr);

}
//字典写入文件
- (void)writeDic {
    NSDictionary *dic = @{@"key":@"value"};
    NSString *str = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)firstObject];
    NSString *toPath = [str stringByAppendingPathComponent:@"dictonry.txt"];
    BOOL isSuccess = [dic writeToFile:toPath atomically:YES];
    NSLog(@"%@",isSuccess ? @"成功" : @"失败");
    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:toPath];
    NSLog(@"%@",dict);
}
//NSData写入文件
- (void)writeData {
    NSString *tempPath = NSTemporaryDirectory();
    NSString *toPath = [tempPath stringByAppendingPathComponent:@"data.txt"];
    NSString *string = @"datadata";
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    BOOL isSuccess = [data writeToFile:toPath atomically:YES];
    NSLog(@"%@",isSuccess ? @"成功" : @"失败");
    NSData *getData = [NSData dataWithContentsOfFile:toPath];
    NSString *str = [[NSString alloc] initWithData:getData encoding:NSUTF8StringEncoding];
    NSLog(@"%@",str);
}

2.preference

//Preference
- (void)writeToPreference {
    // NSUserDefaults 继承自NSObject ,单例     通过kvc模式赋值
    NSLog(@"%@",NSHomeDirectory());
    //创建用户索引对象
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setInteger:100 forKey:@"money"];
    //立即同步操作      对preference中的文件进行修改后,立即同步
    [defaults synchronize];
    NSInteger money = [defaults integerForKey:@"money"];
    NSLog(@"%ld",money);
    [defaults setInteger:10000 forKey:@"MyMoney"];
    [defaults synchronize];

    NSInteger you = [defaults integerForKey:@"you"];
    NSLog(@"%ld",(long)you);
    if (money < 10) {
        NSLog(@"there is no money");
    } else {
        NSLog(@"-100");
        money -= 100;
        [defaults setInteger:40 forKey:@"money"];
        [defaults setInteger:1000 forKey:@"YourMoney"];
    }
    // NSUserDefaults 一般存储一些比较小的数据,大部分用来存数值

    //例子:判断用户是否第一次登陆
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    BOOL isFirst = [userDefault boolForKey:@"isFirst"];
    [userDefault setBool:YES forKey:@"isFirst"];
    [userDefault synchronize];
    if (!isFirst) {
        NSLog(@"第一次登陆");
    } else {
        NSLog(@"不是第一次登陆");
    }
}

3.归档 / 反归档

复杂对象写入文件需要使用归档 ,读取需要使用反归档,不能直接写入文件,数组中有复杂对象也要使用归档 / 反归档

复杂对象使用行归档和反归档,需要遵循NSCoding协议,并实现协议中- (void)encodeWithCoder:(NSCoder *)aCoder;   - (id)initWithCoder:(NSCoder *)aDecoder; 两个方法

新建Person类

在Person.h中 遵循协议

//
//  Person.h
//  07.24-DataPersistiser
//
//  Created by lanouhn on 14/7/24.
//  Copyright (c) 2014年 LCD. All rights reserved.
//

#import <Foundation/Foundation.h>

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

在Person.m中实现协议方法

//
//  Person.m
//  07.24-DataPersistiser
//
//  Created by lanouhn on 14/7/24.
//  Copyright (c) 2014年 LCD. All rights reserved.
//

#import "Person.h"

@implementation Person

//当要归档时,对象会自动触发这个方法
- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.gender forKey:@"gender"];
    [aCoder encodeObject:@(self.age) forKey:@"age"];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    if (self) {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.gender = [aDecoder decodeObjectForKey:@"gender"];
        self.age = [[aDecoder decodeObjectForKey:@"age"] integerValue];
    }
    return self;
}
@end

归档 / 反归档

- (void)archiver {

    //把复杂文件写入文件,先转化为nsdata对象
    //归档:归档的实质就是把其他类型的数据(person),先转化为NSData,再写入文件。
    Person *person = [[Person alloc] initWithName:@"rose" gender:@"girl" age:25];
    //    NSKeyedArchiver  压缩工具类,继承自NSCoder,主要用于编码
    NSMutableData *data = [NSMutableData data] ;
    NSKeyedArchiver *achiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    //使用压缩工具讲Person压到data中
    [achiver encodeObject:person forKey:@"person"];
    //完成压缩,停掉压缩工具
    [achiver finishEncoding];

    NSString *homePath = NSHomeDirectory();
    NSString *toPath = [homePath stringByAppendingPathComponent:@"person.txt"];
    BOOL isSuccess = [data writeToFile:toPath atomically:YES];
    NSLog(@"%@",isSuccess ? @"成功" : @"失败");

    //复杂对象的读取,反归档
    //    NSKeyedUnarchiver
    NSData *getData = [NSData dataWithContentsOfFile:toPath];
    NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:getData];
    //解压
    Person *p1 = [unArchiver decodeObjectForKey:@"person"];
    [unArchiver finishDecoding];
}
 //集合NSArray NSDictionary 如果想进行归档和反归档,那么它里边存储的元素也要遵循NSCoding协议
    Person *person1 = [[Person alloc] initWithName:@"jack" gender:@"男" age:20];
    Person *person2 = [[Person alloc] initWithName:@"rose" gender:@"女" age:20];
    NSArray *array = @[person1,person2];

    NSMutableData *data = [NSMutableData data];

    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:array forKey:@"array"];
    [archiver finishEncoding];

    NSString *tmpPath = NSTemporaryDirectory();
    NSString *toPath = [tmpPath stringByAppendingString:@"array.txt"];

    BOOL isSuccess = [data writeToFile:toPath atomically:YES];
    NSLog(@"%@",isSuccess ? @"成功" : @"失败");
    //反归档
    NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    NSArray *unArchiverArray = [unArchiver decodeObjectForKey:@"array"];
时间: 2024-10-16 16:45:23

iOS数据持久化(一)的相关文章

iOS数据持久化存储

本文中的代码托管在github上:https://github.com/WindyShade/DataSaveMethods 相对复杂的App仅靠内存的数据肯定无法满足,数据写磁盘作持久化存储是几乎每个客户端软件都需要做的.简单如"是否第一次打开"的BOOL值,大到游戏的进度和状态等数据,都需要进行本地持久化存储.这些数据的存储本质上就是写磁盘存文件,原始一点可以用iOS本身支持有NSFileManager这样的API,或者干脆C语言fwrite/fread,Cocoa Touch本身

IOS数据持久化之归档NSKeyedArchiver

IOS数据持久化的方式分为三种: 属性列表 (自定义的Property List .NSUserDefaults) 归档 (NSKeyedArchiver) 数据库 (SQLite.Core Data.第三方类库等) 下面主要来介绍一个归档NSKeyedArchiver. 归档(又名序列化),把对象转为字节码,以文件的形式存储到磁盘上:程序运行过程中或者当再次重写打开程序的时候,可以通过解归档(反序列化)还原这些对象. 归档方式: 对Foundation框架中对象进行归档 对自定义的内容进行归档

iOS数据持久化方式分析

iOS数据持久化的方式一般为:plist文件写入.对象归档.SQLite数据库.CoreData. plist文件写入.对象归档一般用于小的数据量. SQLite数据库.CoreData则用于大的数据量. SQLite是一款轻型的数据库,是一种关系型数据库管理系统,他的设计目的是嵌入式设备中使用. SQLite占用资源非常低,非常适合移动设备中使用,而且是开源免费的 SQLite的数据库操作其实和常规的数据库操作流程是一样的: 1.打开数据库 sqlite3_open() 2.准备SQL语句,采

iOS数据持久化之二——归档与设计可存储化的数据模型基类

iOS数据持久化之二--归档与设计可存储化的数据模型基类 一.引言 在上一篇博客中,我们介绍了用plist文件进行数据持久化的方法.虽然简单易用,但随着开发的深入,你会发现,这种方式还是有很大的局限性.试想,如果我们可以将用户的登录返回信息模型,游戏中角色的属性信息模型进行直接的持久化存取,那是不是非常爽的事,幸运的是,我们可以通过归档,来设计一个这样的数据模型. 二.先来精通归档吧 归档也是iOS提供给开发者的一种数据存储的方式,事实上,几乎所有的数据类型都可以通过归档来进行存取.其存储与读取

iOS开发笔记-swift实现iOS数据持久化之归档NSKeyedArchiver

IOS数据持久化的方式分为三种: 属性列表 (plist.NSUserDefaults) 归档 (NSKeyedArchiver) 数据库 (SQLite.Core Data.第三方类库等 归档(又名序列化),把对象转为字节码,以文件的形式存储到磁盘上:程序运行过程中或者当再次重写打开程序的时候,可以通过解归档(反序列化)还原这些对象.本文主要介绍swift实现iOS数据归档. 归档Foundation框架对象 func archiveData(){ var path: AnyObject=NS

iOS -数据持久化方式-以真实项目讲解

前面已经讲解了SQLite,FMDB以及CoreData的基本操作和代码讲解(CoreData也在不断学习中,上篇博客也会不断更新中).本篇我们将讲述在实际开发中,所使用的iOS数据持久化的方式以及怎么会使用到这些方式,都会以本人实际开发的场景为例,大约需要花10-15分钟,欢迎大家指正. 一.前言 和大家说一个真实故事,前年我去美图面试(当时的技术仅仅是UI和接口的实现,并不注重很多底层实现和很多概念的原理,换句话说,就是真正的码农),过了技术第一轮和第二轮(前两年的也就是问问技术点的实现),

iOS 数据持久化4种方式

iOS 4种讲数据持久存储到iOS文件的系统机制: 属性列表(NSUserDefaults.plist文件) 对象归档(NSCoding) iOS嵌入式关系数据库(SQLite3) 苹果提供的持久化工具(Core Data) 说道数据持久化都涉及到一个共同的要素.既然是把数据持久存储到iOS文件系统中,那么久涉及到了应用沙盒. 可以尝试使用Xcode建立一个空的应用,然后打开应用目录可以查看到有以下文件 1.Documents ①存放内容 我们可以将应用程序的数据文件保存在该目录下.不过这些数据

IOS数据持久化的4种方式

9.1 数据持久化概述 9.2 iOS应用程序目录结构 9.3 读写属性列表 9.4 对象归档 9.5 访问SQLite 9.1 数据持久化概述 iOS中可以有四种持久化数据的方式: 属性列表.对象归档.SQLite3和Core Data 9.2 iOS应用程序目录结构 iOS应用程序运行在Mac os模拟器时候,有一下临时目录模拟器3.1.3为例子: /Users/tony/Library/Application Support/iPhone Simulator/3.1.3/Applicati

IOS数据持久化之归档NSKeyedArchiver, NSUserDefaults,writeToFile

//2.文件读写 //支持:NSString, NSArray , NSDictionay, NSData //注:集合(NSArray, NSDictionay)中得元素也必须是这四种类型, 才能够进行文件读写 //string文件读写 NSString *string = @"假如给我有索纳塔"; //Document NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUs

iOS数据持久化之---属性列表

属性列表(plist) iOS提供了一种plist格式的文件(属性列表)用于存储轻量级的数据,并且只能保存NSDictionary.NSArray.NSString.NSNumber.Boolean.NSData.NSDate 类型的数据.将这些类型的数据保存为plist格式文件,该格式保存的数据可以直接使用NSDictionary和NSArray读取 (一).使用NSUserDefault 实现持久化   下面来看下 NSUserDefault 本地保存的位置,数据持久化之沙盒目录有提及.Li