有时候应用内需要拍照。需要存储一些txt的文本信息,需要保存一些字符串等等,这时候需要存储到本地或者cache缓存内。了解了一下并且自己写了个demo测试一下后,有一些自己的理解,记录下来方便以后查询用
首先,iOS的应用每个都有自己的文件夹,也叫沙盒。用来存储自己应用内的一些数据,外部app无法访问
其次。根据你的需求不同,你需要的数据持久化类型也可能不同,有的数据想一直存储在本地随时可能会来读写内容,而且需要连接iTunes时有必要备份的,有的只是作为缓存,退出app后就清除掉了,有的比如视频缓存等一些文件不用备份也不想退出app就删除掉的这种数据,根据几种需求的不同,iOS给出了这么几种保存数据的文件夹,document,tmp,libarary,catche等,其中:
Documents:苹果建议将程序创建产生的文件以及应用浏览产生的文件数据保存在该目录下,iTunes备份和恢复的时候会包括此目录
Library:存储程序的默认设置或其它状态信息;
Library下的Caches文件夹:存放缓存文件,保存应用的持久化数据,用于应用升级或者应用关闭后的数据保存,不会被itunes同步,所以为了减少同步的时间,可以考虑将一些比较大的文件而又不需要备份的文件放到这个目录下。
tmp:提供一个即时创建临时文件的地方,但不需要持久化,在应用关闭后,该目录下的数据将删除,也可能系统在程序不运行的时候
了解了这几个文件夹的用途和使用场景。下面进入代码部分
当你确定你有了数据持久化的需要后,无论你是要存储还是要读取首先要做的是
//首先创建文件管理器,用于判断文件存不存在
//第一步 在Documents里创建目录
NSFileManager * manager=[NSFileManager defaultManager];
//取路径(比如我现在要存或者要取的数据,是需要在document目录中的)则获取应用的Documents目录,如果是缓存的,可以将下面的代码中NSDocumentDirectory缓存NSCacheDirectory,其他的如tmp和libarary都类似
// NSSearchPathForDirectoriesInDomains 返回绝对路径
// NSDocumentDirectory 要查找的目录
// NSUserDomainMask 是否是用户主目录,标识从用户文件夹下找
//YES/NO 是否获取全路径,即展开路径中的波浪字符@“~”
//[array lastObject] 只有一个匹配目录,所以这个集合里面只有一个元素
NSString * documentPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
//使用字符串拼接的方式获取目录名,或者是你要创建的话,写上你要创建的目录名(上面拿到的路径拼接名字)
NSString * filePath=[documentPath stringByAppendingPathComponent:@"testa"];
if ([manager fileExistsAtPath:filePath]) {
NSLog(@"目录存在");
}
//如果不存在,就在filemanager创建目录
else{
NSLog(@"目录不存在,创建了对应的目录");
[manager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
}
NSLog(@"目录路径:%@",filePath);
//第二步 在目录下创建文件 并存储data
NSString * content=@"哈哈,这是内容 nsstring!!!";
NSArray * imar=@[@"dianpuxinxi_press.png",@"dianpuxinxi.png",@"zengjiashangpin.png",@"zengjiashegnpin_press.png"];
for (int i=0; i<4; i++) {
//存储图片
NSData * data=UIImageJPEGRepresentation([UIImage imageNamed:imar[i]],0.25);//压缩图片
NSString * pathTest=[filePath stringByAppendingPathComponent:[NSString stringWithFormat:@"test%d.jpg",i]];//创建保存的4张图片的文件名字
[manager createFileAtPath:pathTest contents:data attributes:nil];//存入图片
// 存储文本
NSString * pathTest1=[filePath stringByAppendingPathComponent:[NSString stringWithFormat:@"testddd%d.txt",i]];
[manager createFileAtPath:pathTest1 contents:[content dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];
//存储的方式有两种,文件主动存储内容调用类似Read方法 和 内容主动写入到文件调用Write方法 上面的是文件主动Read存储,下面的是内容主动write到文件方法 两种方法在我测试后,均可达到写入文件的目的。其他的区别暂时还不知道,望大神告知。
[content writeToFile:pathTest1 atomically:YES encoding:NSUTF8StringEncoding error:nil];
获取目录列里所有文件名
//两种方法获取:subpathsOfDirectoryAtPath 和subpathsAtPath
NSArray * file1=[manager subpathsOfDirectoryAtPath:filePath error:nil];
NSArray * file=[manager subpathsAtPath:filePath];
NSLog(@"%@",file);
NSLog(@"%@",file1);
//以上,就可以打印出你创建的目录里面的所有文件了,file和file1 打印结果是相同的,两种获取方法用那种都可以。
//现在问题来了。如果我是写入一些NSString进入文件,第一次传了一个@“1234556”进去,然后我接着在下面又写入了一个一个@“987654”,是什么样的呢?
//告诉你们。打印效果是“987654” 意思就是后面的把前面的给覆盖掉了。这时候就需要对你存储data的文件操作的一个类NSFileHandle 这个类来帮助你将特定的字符串写入到沙盒中的文件中,追加而不是覆盖
//读取文件类和常用方法
//NSFileHandle类主要对文件内容进行读取和写入操作
//NSFileManager类主要对文件的操作(删除、修改、移动、复制等等)
// 初始化,对目标txt文件操作。
NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:pathTest1];
[fileHandle seekToEndOfFile]; //将节点跳到文件的末尾
[fileHandle writeData:stringData]; //追加写入数据
[fileHandle closeFile];
大体就是这样了,如果想对文件进行更细致的操作,可以查阅fileHandle这个类的其他方法。我查看了几个方法,都是以后会用到的,在这里给大家标明一下:
常用处理方法
+ (id)fileHandleForReadingAtPath:(NSString *)path //打开一个文件准备读取
+ (id)fileHandleForWritingAtPath:(NSString *)path //打开一个文件准备写入
+ (id)fileHandleForUpdatingAtPath:(NSString *)path //打开一个文件准备更新
- (NSData *)availableData; //从设备或通道返回可用的数据
- (NSData *)readDataToEndOfFile; //从当前的节点读取到文件的末尾
- (NSData *)readDataOfLength:(NSUInteger)length; //从当前节点开始读取指定的长度数据
- (void)writeData:(NSData *)data; //写入数据
- (unsigned long long)offsetInFile; //获取当前文件的偏移量
- (void)seekToFileOffset:(unsigned long long)offset; //跳到指定文件的偏移量
- (unsigned long long)seekToEndOfFile; //跳到文件末尾
- (void)truncateFileAtOffset:(unsigned long long)offset; //将文件的长度设为offset字节
- (void)closeFile; 关闭文件
好了,希望对大家有帮助,过几天来看的时候希望我还记得现在记下的这些东西~