OC第八节——目录操作和文件管理
1.需要理解的知识
通常程序在运行中或者程序结束之后,需要保存一些信息,而且需要持久化存储信息,比如登陆信息、视频播放记录、收藏记录等等,那么我们可以采用以下几种方式对数据进行持久化保存.
1.文件
2.plist
3.归档
1.1单例模式
单例模式是一种常用的设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在,而且自行实例化并向整个系统提供这个实例。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
其实单例类似C语言中的全局变量的结构体
在整个程序生命周期内,该对象只有一份实例存在内存中
单例的作用:
1. 可以在多个对象之间共享数据;
2. 如果创建一个对象,要消耗很大的性能,可以选择使用单例。
<1>非标准的单例设计
单例的创建方法通常以default/shared开头
+ (MyPlane *)defaultPlane{
static MyPlane * plane = nil;
@synchronized(self){
if (!plane) {
plane = [[self alloc]init];
}
}
return plane;
}
//或者
+ (MyPlane *)sharePlane{
static MyPlane * plane = nil;
@synchronized(self){
if (!plane) {
plane = [[self alloc]init];
}
}
return plane;
}
单例不需要release 或者 autorelease ,因为单例的生命周期为整个程序。
1.2文件
<1>文件管理类NSFileManager
1.NSFileManager 是一个单例类
对文件进行管理,必须要获取文件管理器NSFileManager类的对象
NSFileManager * fm = [NSFileManager defaultManager];
2.对文件进行管理操作
a.遍历查看目录下的文件
b.创建文件/目录(文件夹)
c.拷贝文件/目录
d.移动文件/目录
e.删除文件/目录
<2>文件句柄类NSFileHandle
1.对文件进行读写首先需要NSFileHandle打开文件
2.NSFileHandle对文件进行读写都是NSData类型的二进制数据
3.NSData与NSString之间的相互转换
2.需要记住的知识
2.1 NSFileManager
<1>创建文件管理器单例对象
NSFileManager * fm = [NSFileManager defaultManager];
<2>遍历目录下的内容
//浅度遍历
- (NSArray *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error;
//深度遍历
- (NSArray *)subpathsOfDirectoryAtPath:(NSString *)path error:(NSError **)error
<3>判断文件是否存在
- (BOOL)fileExistsAtPath:(NSString *)path;
<4>创建文件
//创建普通文件
- (BOOL)createFileAtPath:(NSString *)path contents:
(NSData *)data attributes:(NSDictionary *)attr;
//创建目录
- (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories: (BOOL)createIntermediates attributes:(NSDictionary *)attributes error:(NSError **)error ;
<5>拷贝文件/目录
- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error ;
<6>移动文件/目录
- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error ;
<7>删除文件/目录
- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error;
<8>获取文件属性
- (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error;
2.2 NSFileHandle
2.2.1方法:
<1>打开文件方法
//以只读方式打开
+ (id)fileHandleForReadingAtPath:(NSString *)path;
//以只写方式打开
+ (id)fileHandleForWritingAtPath:(NSString *)path;
//以读写方式打开
+ (id)fileHandleForUpdatingAtPath:(NSString *)path;
<2>读指定长度的数据
- (NSData *)readDataOfLength:(NSUInteger)length;
<3>从当前偏移量读到文件尾
- (NSData *)readDataToEndOfFile;
<4>设置文件偏移量
- (void)seekToFileOffset:(unsigned long long)offset;
<5>将文件偏移量定位到文件尾
- (unsigned long long)seekToEndOfFile;
<6>写文件
- (void)writeData:(NSData *)data;
2.3 NSData
//如果把字符串转化为NSData
NSString *str = @"welcome to beijing";
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
//NSData 转化为字符串
NSString *newStr = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
3 Plist
<1> 什么是plist文件, plist文件的作用
1.plist文件:property list 属性列表文件,文件的内容只能是 NSString NSNumber NSDate NSData NSArray NSDictionary类的对象内容, 不能保存其他类型数据.
2.作用:对一些登陆注册信息或者程序的配置信息(小数据)进行持久化存储
<2> 如何创建plist文件, 如何编辑plist文件
Plist文件内容的格式是XML语法格式
1.Xcode创建
1.点击File—>New File 弹出一对话框
2.iOS程序选中iOS栏中的Resource/Mac程序选中OS X 栏中的resource
3.点击Resource中的Property List 创建plist文件
4.点击文件中的'+'可以添加数据
2.代码创建
如果要把 NSString NSNumber NSDate NSData NSArray NSDictionary 的对象写入文件一般就用plist文件
我们需要这些数据保存到一个数组或者字典中,然后调用数组和字典的相关函数把数 组NSArray或者字典NSDictionary写入plist文件
//NSArray和NSDictionary写文件方法
- (BOOL)writeToFile:(NSString *)path atomically:
(BOOL)useAuxiliaryFile;
<3> 如何在程序中读取plist文件数据
Plist文件的根节点(数据的最外层)通常是数组或者字典
如果Plist文件的根节点是字典那么使用字典的类方法
+ (id)dictionaryWithContentsOfFile:(NSString *)path;
读写Plist文件
如果根节点是数组那么使用数组的类方法
+ (id)arrayWithContentsOfFile:(NSString *)path;
读取Plist文件。
注:上述两个方法只能读取Plist文件,不能读取其他格式的文件。
4 归档
<1>什么是归档和解档
1.归档(也称对象序列化)就是通过某种格式把对象保存到本地文件,以便以后
读回该对象的内容
2.解档(也称归档/读档)就是把归档的对象文件读成原来的对象的过程。
<2>如何归档和解档
1.系统类的归档和解档
2.归档的对象包括这个对象中的属性,它们所属类的都必须要遵守NSCoding
协议才能归档和解档
<3>.自定义类的归档和解档
如果自定义的类对象要进行归档那么这个对象的属性所属的类也必须要遵守
归档协议NSCoding
必须实现以下两个方法:
//归档的时候调用的方法
- (void)encodeWithCoder:(NSCoder *)aCoder;
//解归档的时候要调用的函数
- (id)initWithCoder:(NSCoder *)aDecoder;
#import <Foundation/Foundation.h> @interface Person : NSObject <NSCoding> @property (nonatomic, copy) NSString *name; @property (nonatomic, assign) NSInteger age; @property (nonatomic, retain) NSArray *parent; @end #import "Person.h" @implementation Person //归档时,自动调用的方法 - (void)encodeWithCoder:(NSCoder *)aCoder { // NSArchiver 继承于NSCoder //将对象里面的每一项都进行归档 [aCoder encodeObject:self.name forKey:@"name"]; [aCoder encodeInteger:self.age forKey:@"age"]; [aCoder encodeObject:self.parent forKey:@"parent"]; } //构造方法--解档 - (id)initWithCoder:(NSCoder *)aDecoder { self = [super init]; if (self) { self.name = [aDecoder decodeObjectForKey:@"name"]; self.age = [aDecoder decodeIntegerForKey:@"age"]; self.parent = [aDecoder decodeObjectForKey:@"parent"]; } return self; } - (NSString *)description { return [NSString stringWithFormat:@"name: %@, age: %ld, parent: %@", _name,_age,_parent]; } #import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person *xiaoming = [[Person alloc] init]; xiaoming.name = @"xiaoming"; xiaoming.age = 20; xiaoming.parent = @[@"laoming",@"cuihua"]; //xioaming ---> 归档成文件 //能够使用归档方法---> 遵守NSCoding协议 BOOL ret = [NSKeyedArchiver archiveRootObject:xiaoming toFile:@"/Users/mac/Desktop/person.arc"]; if (ret) { NSLog(@"归档成功"); }else { NSLog(@"归档失败"); } Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/mac/Desktop/person.arc"]; NSLog(@"person = %@", person); } return 0; }