沙盒机制与NSFileManager与数据持久化--归档和读写和NSUserDefaults

1、 NSDocumentDirectory 表示查找的是document目录, NSUserDomainMask是指查找的范围是所在程序的沙盒,YES指定了是否展开波浪线;在MAC系统中 ~代表主路径 (Home) 如果不展开 路径就如 ~/Document,如果展开就是完整的路径  一般都设为YES  

2、NSSearchPathForDirectoriesInDomains 函数的返回值不是想象中的表示全路径的字符串,而是一个数组,因为这组函数 是和 Mac OS 通用的,在最初设计时主要针对 Mac OS。在 Mac OS 中,可能有多个这 样的路径,所以就可能不止一个结果,这些路径都将被放置到返回的数组中,在 iPhone 系统中,每个应用程序都有唯一的主路径,因此不需要考虑,直接取返回数组的第一个 元素,就得到了 Documents 的全路径。


bundle是一个目录,其中包含了程序会使用到的资源. 这些资源包含了如图像,声音,编译好的代码,nib文件


我们的程序是一个bundle. 在Finder中,一个应用程序看上去和其他文件没有什么区别. 但是实际上它是一个包含了nib文件,编译代码,以及其他资源的目录. 我们把这个目录叫做程序的main bundle

NSBundle *myBundle = [NSBundle mainBundle];

- (NSString *)pathForResource:(NSString *)name ofType:(NSString *)fileType;


沙盒是一种安全机制放置不同应用之间的相互访问 在Finder中前往可以访问到 

沙盒根目录名称随机生成应用ID

Documents目录主要存放程序中的文件数据 (备份)

Library目录中的preferences存放基于NSUserDefaults的设置数据如plist文件(备份) caches存临时文件程序退出清空

tmp目录存放临时文件

xxx.app应用程序包存nib,图片,音频


根目录:NSHomeDirectory() 

xxx.app程序包:[ [NSBundle mainBundle] pathForResource:@"1" ofType:@"jpg"];

Documents、Library、Caches目录: 

NSArray *paths = NSSearchPathForDirectoriesInDomains(  NSUserDomainMask, YES); //这个返回的是一个数组而不是string路径

NSString *directory = [paths objectAtIndex:0];

NSString *fileName = [documentsDirectory stringByAppendingPathComponent:@"xxx.plist"]

tmp目录:NSTemporaryDirectory() NSLibraryDirectory








文件是数据在输出介质上的存储形式  目录是文件的组织形式
除了系统的读取方法外还可以用 NSFileManager
字节数据的缓冲类NSData和NSMutableData 可以用来进行文件操作时的读写中介体

NSFileManager *fileManager = [NSFileManager defaultManager];

BOOL flag = [fileManager createFileAtPath:fileName contents:data attributes:nil];//文件属性

if ([fileManager fileExistsAtPath:fileName])//NSFileManager需要判断文件是否存在

{NSData *readData = [[NSData allocinitWithContentsOfFile:fileName];

            NSString *readString = [[NSString allocinitWithData:readData encoding:NSUTF8StringEncoding];

[fileManager removeItemAtPath:fileName error:&error];

}


之前的程序在运行时都是将数据(NSArray、NSDictionary、NSString等)存放在内存中的,当程序退出后这些数据就会丢失。这样造成的影响就是,当下次程序运行时,没办法保留之前的状态,所以就需要在程序发生某些更改变动时,将这些更改的内容存储到文件中,这时当程序再次运行时可以通过读取文件中的内容来设置程序状态。其实这三种方式都是把数据存储到本地文件里边,只是实现方式和使用的场景不同而已,复杂程度从上到下增加。----文件读写 归档序列化 嵌入式数据库(sqlite3) CoreData iCloud

读initWithContentsOfFile   写writeToFile: atomically: 文件路径 将该值设置为 YES 后,写入文件的时候,将不会直接写入指定路径,而 是会将数据写入一个“辅助文件”,写入成功后,再将辅助文件复制到指定路径。如此, 实际操作的对象是辅助文件,从而可以避免源文件数据损坏 

优缺点:操作简单 只有当数据类型为数组字典且其内部元素也要是NSArray NSDictionary NSString NSData 简单存储

归档要求是基本类型或者遵循NSCoding协议的类的对象NSArray NSString 实际上就是把数据线转换为NSData为了读取数据需要编码和解码 encodeWithCoder和initWithCoder 

优缺点:解决自定义类的存储问题 查询数据需要先读出来然后再去找属性

NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:]

[archiver encodeObject:stu forKey:@"stuKey"];//调用encodeWithCoder方法里面实现的方法就是如前所述 简直编码

[archiver finishEncoding];

[data writeToFile:[self filePathByName:@"yyyyy.plist"] atomically:YES];//写文件到归档文件

if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])//反归档文件首先用文件管理者查下是否已经存在归档的文件

NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];

Student *stu = (Student *) [unarchiver decodeObjectForKey:@"stuKey"];//会调用initWithCoder方法 里面实现的方法就是如前所述

[unarchiver finishDecoding];


读写图片比较特殊方法是

NSData *imageData = UIImagePNGPresentation(image);

[imageData writeToFile:filePath atomically:YES];//写图片

[UIImage imageWithContentsOfFile:filePath];//读图片


数据类型之间的转换

1,NSData 与 NSString

NSString *aString = [[NSString alloc] initWithData:adata encoding:NSUTF8StringEncoding];

NSData *aData = [aString dataUsingEncoding: NSUTF8StringEncoding];
2,NSData 与 UIImage
UIImage *aimage = [UIImage imageWithData: imageData];(一般NSData可以通过   [NSData dataWithContentsOfFile: finalPath]或 [[NSData alloc] initWithContentsOfFile: mp3Path1] 获取到
NSData *imageData = UIImagePNGRepresentation(aimae);
4,NSData 与 NSMutableData
[NSData dataWithData:data];


[sounds writeToFile:[self filePathWithName:@"tmp.mp3"] atomically:YES];







NSUserDefaults 类用于保存应用程序设置和属性以及用户数据 且 数据是存储在文件系统中而不是作为一个对象实例放在内存中   只支持: NSString, NSNumber, NSDate, NSArray, NSDictionary.
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 
 [userDefaults setFloat:myFloat forKey:@"myFloat"];
[userdefaults synchronize];
NSInteger myInteger = [userDefaultes integerForKey:@"myInteger"]; 

一个set一个integerForKey就搞定了 但如果遇到自定义的类的话就同样要实现initWithCoder和encodeWithCoder的归档作为中间载体


   
   
     
     
     
     
  1. BusinessCard *bc = [[BusinessCard alloc] init];  
  2. NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];  
  3. NSData *udObject = [NSKeyedArchiver archivedDataWithRootObject:bc];  
  4. [ud setObject:udObject forKey:@"myBusinessCard"];  
  5. [bc release];  
  6. udObject = nil;  
  7. udObject = [ud objectForKey:@"myBusinessCard"];  
  8. bc = [NSKeyedUnarchiver unarchiveObjectWithData:udObject] ;  

saveNSUserDefaults:用于将各种类型数据保存到NSUserDefaults中
readNSUserDefautls:用于从NSUserDefaults中读取各种类型的数据

在Settings Bundle中使用plist文件来定义程序中允许的设置项,Settings程序会自动建立接口 参考单独的记事文件




数据库:sqlite FMDatabase
导入三方类库和sqlite3类库并添加相应头文件到使用位置 创建路径一般都在沙盒Document文件中
NSString *paths = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0];
NSString *dbPath = [paths stringByAppendingPathComponent:@"Test.db"];
FMDatabase *db = [FMDatabase databaseWithPath:dbPath];
if([db open])
{NSLog(@"It's OK"); }
创建一个表[db executeUpdate:@"CREATE TABLE User (Name text,Age integer)"];//使用到FMDatabase和sqlite语句 名为User的表 两字段 
插入一个对象 [db executeUpdate:@"INSERT INTO User (Name,Age) VALUES (?,?),@"张三",[NSNumber numberWithInt:20]"];
更新一个对象 [db executeUpdate:@"UPDATE User SET Name = ? WHERE Name = ?",@"李四",@"张三"];
删除一个对象 [db executeUpdate:@"DELETE FROM User WHERE Name = ?",@"李四"];
查询对象 
FMResultSet *resultSet = [db executeQuery:@"SELECT *FROM User"];
resultSet = [db executeQuery:@"SELECT *FROM User WHERE Age = ?",@"20"]; //*号代表所有 ?号代表
while ([resultSet next])
{NSLog(@"%@ %@",[resultSet stringFormColumn:@"Name"],[resultSet stringFormColumn:@"Age"]);}

[resultSet close];

另外有一个查询方法需要导入另一个头文件

NSString *result = [fmDatabase stringForQuery:@"select name from student where age = ?",@"27"]//这个搜索局部的需要添加FMDatabaseAdditions.h头文件




SQL的学习
  • NULL. 空值

  • INTEGER. 整型

  • REAL.浮点型

  • TEXT.文本类型

  • BLOB. 二进制类型,用来存储文件,比如图片。


句柄是物体的描述结构体。(很长的系统代码)
创建一个句柄:sqlite3* pdb; 
在shell下键入(以下$符号为shell提示号,请勿键入):$ sqlite3 foo.db  如果目录下没有foo.db,sqlite3就会建立这个数据库  

if (sqlite3_open([databaseFilePath UTF8String], &database)==SQLITE_OK) 
{
  NSLog(@"sqlite dadabase is opened."); 
}
所有SQL语句以分号结尾;
建立资料库 create table film(title, length, year, starring);意思是包含四个字段
建立索引 create index film_title_index on film(title);意思是建立电影名称的索引
添加资料 insert into table_name values(data1, data2, data3, ...);
       比如 insert into film values ('Hours, The', 114, 2002, 'Nicole Kidman');
查询资料 select columns from table_name where expression;       
        select * from film; 可以直接在film空格后加上查询限制limit 10 
        select * from film order by year limit 10; year后面加个desc是降序即由近往远排序
        select title, year from film order by year desc limit 10;查询多个
        select * from film where starring='Jodie Foster';
        select * from film where starring like 'Jodie%';
        select title, year from film where starring like 'Jodie%' and year >= 1985 order by year desc limit 10;
        select count(*) from film; 个数
        select count(*) from film where year >= 1985;
更新和删除
        update film set starring='Jodie Foster' where starring='Jodee Foster';
        delete from film where year < 1970;
 

你可能感兴趣的:(沙盒机制与NSFileManager与数据持久化--归档和读写和NSUserDefaults)