文件存储

文件存储

文件存储基础

沙盒模型

手机中的沙盒:

  • 安全
  • 隐私
  • 整洁

磁盘空间比较小的时候,提供会对library内的部分文件进行清理。
Documents下的文件不会被清理。

Bundle Container

App内找文件->Bundle->文件名->对应文件

对应代码:
[[NSBundle mainBundle] pathForReasource:@"name" ofType:@"type"];

Data Container

//Home目录,即最外层目录
 NSHomeDirectory();

//Home目录,目录下子目录
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

//Temp目录
NSTemporaryDirectory();

资源管理器

  1. 发现资源(遍历目录)
  2. 修改资源 (创建/删除目录, 创建/删除文件, 修改目录, 读取文件)

NSFileManager
用于文件读写,目录遍历,目录/文件创建,复制,移动,删除...

使用方法:
NSFileManager *manager = [[NSFileManager alloc] init];
NSFileManager *defaultManager = [NSFileManager defaultManager];//单例

内置存储

NSUserDefaults

NSUserDefaults可以存储:

NSString
NSData
NSDate
NSArray
NSDictionary
NSNumber
BOOL,Integer,Float,Double

总结

NSUserDefaults实际上就是个.plist文件
只适合存储一些小的数据。比如用户名,游戏的最高分等等
无加密,不能存储机密文件
一个App只有一个NSUserDefaults

propertyList

当有很多份数据,或不同种数据需要在不同的plist文件中时,就不能使用NSUserDefaults,因为它只有一个。

             writeToFile:atomically:
   NSArray---------------------------->file.plist
file.plist---------------------------->NSArray
             arrayWithContentsOfFile:
             
             writeToFile:atomically:
NSDictionary---------------------------->file.plist
  file.plist---------------------------->NSDictionary
             dictionaryWithContentsOfFile:

对象归档

NSDictionary is Not a Model
可读性差

model的特性

可读性
可维护性

将对象归档的方法

  1. 创建一个自定义的对象,需遵循NSCoding协议。需实现:
- encodeWithCoder:    //将对象转为特定的数据流
- initWithCoder:      //将文件转为特定的对象
  1. 使用以下方法对文件进行读写:
NSKeyedArchiver
NSKeyedUnarchiver

SQLite

之前文件存储的方法缺点:

无论多小的改动,都是将所有的数据写入文件
所有的数据都是一次性加载到内存

SQL(Structural Query Language)

  • 建表
  • 插入数据
  • 查询数据
  • 删除数据
  • 更新数据

SQL-建表

建表 create table
表名 members
列名 id,name,gender,mobile
列类型 text,integer,blob

create table if not members (id integer primary key autoincrement, name text, gender integer, mobile text)

SQL-插入

更新 insert into
表名 members
列名 name,gender,mobile
列内容 '小明', '1', '133323'

insert into member (name, gender, mobile) values ('小明',‘1’,‘133323’)

SQL-读取

读取 select from
内容 */entity
表名 members
条件 where/order/group/limit/offset/having

SQL-删除

删除 delete from
表名 members
条件 where

在iOS工程中使用SQLite

在工程中引入SQLite库
import SQLite头文件 #import<sqlite.h>
调用SQLite API (C API)

SQLite API:

打开数据库

int sqlite3_open (
    const char *filename,
    sqlite3 **ppDb
);

关闭数据库

int sqlite3_close(sqlite3*);

执行SQL语句

int sqlite3)exec (
    sqlite3*,
    const char *sql,
    int (*callback) (void*, int, char**, char**),
    void *,
    char **errmsg;
);

准备SQL语句

int sqlite3_prepare(
    sqlite3 *db;            // Database handle
    const char *zSql;       // SQL statement, UTF-8 encoded
    int nByte,              // Maximum length of zSql in bytes
    sqlite3_stmt **ppStmt,  // 将sql语句的字符串,转化为sql语句的结构体
    const char **pzTail     // 如何sql语句过长,而且没有准确描述sql语句的长度,则会将超出的字符串截取到该指针中
);

执行

int sqlite_step(sqlite3_stmt *);

清理

int sqlite3_finalize(sqlite3_stmt *pStmt);

Beyond the SQLite

SQLite的缺点

大量C <--> OC 转换
手动指定index
手动资源清理
手动绑定数据

使用OC做SQLite C API 的wrapper

@interface Database : NSObject
- (BOOL)open:(NSString *)filepath;
- (BOOL)close;
- (BOOL)exec:(NSString *)sql,...;
- (NSArray *)query:(NSString *)sql,...;
@end
@interface Database() {
    sqlite3 *_db;
}
@end

@implementation Database
- (BOOL)open:(NSString *)filepath {
    const char *filename = [filepath UTF8String];
    return sqlite3_open(filename, &_db) == SQLITE_OK;
}

- (BOOL)close {
    int err = 0;
    if (_db) {
        err = sqlite3_close(_db);
    }
    _db = NULL;
    return err == SQLITE_OK;
}

- (BOOL)exec:(NSString *)sql,... {
    //内部状态判断...
    
    int err = 0;
    sqlite3_stmt *stmt = NULL;
    if ([sqlite3_prepare(_db, [sql UTF8String], -1, &stmt, NULL) == SQLITE_OK) {
        //解析参数
        va_list args;
        va_start(args, sql);
        NSArray *bindArgs = [self parseArguments:args];
        va_end(args);
        
        //绑定参数
        for (NSInteger i = 0; i < [bindArgs count]; i++) {
            [self bindObject:[bindArgs objectAtIndex:i]
                       index:i + 1
                       toStmt:stmt];
        }
        
        //执行
        err = sqlite3_step(stmt);
        
        //回收
        sqlite3_finalize(stmt);
    }
    
    return err == SQLITE_DONE;
}

@end

FMDB
FMDB是成熟的SQLite Objective-C封装

github地址

CoreData

FMDB是很好用,但是写SQL很麻烦,很繁琐。

CoreData优点

没有sql语句
兼容性强
苹果主推

CoreData缺点

学习曲线陡峭
坑多

ORM(Object-Relational Mapping)

CoreData Stack

Objects <--> ORM <--> Database //ORM是对象和数据库之间的衔接。

做存储的第三方库

  • 不会把所有内容存到内存中,有很好的性能
    levelDB

  • 类似CoreData,但比CoreData简单。
    Realm

对比

| plist/对象归档/文件读写 | SQLite | CoreData |
--------- | ------------- | ----- |---
查询速度 | 非常快 | 快(但需要精心设计) | 较快
读写速度 | 随着数据量增大读写速度变慢 | 快,稳定 | 快,稳定
内存占用 | 高 | 低 | 低
复杂度 | 低,使用简单 | 中,使用繁琐 | 高,使用简单
大数据量支持 | 不适宜 | 适宜 | 适宜
适应场景 | 少量数据存储 | 几乎适用所有的场景,对大数据查询有特别好的支持 | 几乎适用所有场景
兼容性 | 兼容性好 | 涉及到数据升级会比较麻烦 | 兼容性好

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 前言 因为这一段时间有需求需要用到文件的存取操作,而之前基本上对于本地数据的存储就是简单数据用NSUserDefa...
    沉默学飞翔阅读 593评论 0 1
  • 在 SQL 数据库中保存数据 将数据保存到数据库对于重复或结构化数据(比如契约信息)而言是理想之选。 本课程假定您...
    李建彪阅读 2,169评论 0 0
  • 转载请注明出处:http://www.jianshu.com/p/21b266d6b6d7[https://www...
    朋永阅读 462评论 0 1
  • 也许生活在这钢筋混泥土之中,早已淡了季节轮回的感触,忽视了做为大自然的有机体,新陈代谢,生生不息的一面。秋天短暂,...
    董泽润阅读 8,656评论 0 10
  • 火车一路走走停停,从北到北,阳光依旧很好,十几个小时的漫长时光,全部凝于指尖,敲出一篇细细长长的文。...
    代暮秋阅读 518评论 7 6