NSFileManager
文件管理器, 是单例, 查看 创建 拷贝 移动 删除 等等
define PATH @"/Users/wangjingsai/Desktop/WeiZhenDir"
NSFileManager *fileManager = [NSFileManager defaultManager];
1.浅层遍历目录
找到路径PATH下面文件/文件夹路径放到一个数组中
没有一层一层的深度找,只是把当前路径下文件/文件夹 名字放到数组中
NSArray *array = [fileManager contentsOfDirectoryAtPath:PATH error:&error];
2 . 深度遍历
把当前路径下文件/文件夹 名字放到数组中
对于它下面的文件夹中的文件也找到,并放到数组中
array = [fileManager subpathsOfDirectoryAtPath:PATH error:nil];
3 . 创建文件
NSString *filePath = [PATH stringByAppendingPathComponent:@"gf_list.txt"]; // 调这个方法会自动的在gf_list.txt前面加一个/
NSString *str = @"1. hello\n2. world";
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
// 第一个参数:文件路径(在哪个路径下创建文件)
// 第二个参数:文件创建时给它写入什么内容(NSData *)
// 第三个参数:文件的属性,写为nil用它默认的属性
// 返回值是YES表示创建成功,否则创建失败
// 判断原来filepath文件是否存在
if ([fileManager fileExistsAtPath:filePath]) {
NSLog(@"文件%@原本就是存在的", filePath);
} else {
// 注意:如果原来文件存在,会把原来文件替换掉,所以一般判断一下原来文件是否已经存在
BOOL ok = [fileManager createFileAtPath:filePath contents:data attributes:nil];
if (ok) {
NSLog(@"创建文件成功");
}
}
4 . 获取文件属性
返回文件filePath的信息,把这些信息存在一个字典中以键值对的形式返回
NSDictionary *fileInfo = [fileManager attributesOfItemAtPath:filePath error:&error];
4 .1 文件大小
NSLog(@"文件大小(以字节为单位):%lld", [fileInfo[NSFileSize] longLongValue]);
// [fileInfo objectForKey:NSFileSize];
// NSFileSize -> key -> 字符串
NSLog(@"获取文件大小方法二(以字节为单位):%lld", [fileInfo fileSize]);
5 . 创建文件夹
NSString *dirPath = [PATH stringByAppendingPathComponent:@"2/3/4"];
/*
返回值:成功YES 失败NO
第一个参数:目标文件夹路径
二: YES :不管中间目录是否存在 都会创建目标文件夹(如果中间目录不存在那么中间目录也会创建)
NO: 如果中间的目录不存在那么不创建
YES: 如果中间的目录不存在那么创建
如果目标文件夹存在,那么不创建新的,直接返回YES (注意,创建文件不是这样,创建文件,如果原文件存在,就替换掉了)
三 文件属性
四 错误信息
*/
if ([fileManager fileExistsAtPath:dirPath]) {
NSLog(@"文件夹本来就存在");
} else {
BOOL ret = [fileManager createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:&error];
if (ret) {
NSLog(@"创建文件夹成功");
} else {
NSLog(@"创建文件夹失败");
}
}
6 . Copy 文件、文件夹
NSString *sourcePath = [PATH stringByAppendingPathComponent:@"gf_list.txt"];
NSString *destPath = [PATH stringByAppendingPathComponent:@"1/xxxxx.txt"];
BOOL ret2 = [fileManager copyItemAtPath:sourcePath toPath:destPath error:&error]; // 目标文件路径和源文件路径不能完全相同
7 . 文件/文件夹的移动&重命名
sourcePath文件 –> 移动到destPath
sourcePath = [PATH stringByAppendingPathComponent:@"gf_list.txt"];
destPath = [PATH stringByAppendingPathComponent:@"wife_list.txt"];
BOOL success = [fileManager moveItemAtPath:sourcePath toPath:destPath error:nil]; // 注:不能把文件移动到和它同目录并同名的文件上 sourcePath != destPath 移动成功后,原文件没有了,放在了destPath标识的文件中,并且可以重命名:gf_list.txt -> wife_list.txt
8 . 删除文件
文件删除 :谨慎 使用 不会把删除的文件放在废纸篓中
BOOL flag = [fileManager removeItemAtPath:[PATH stringByAppendingPathComponent:@"gf_list.txt"] error:nil];
NSFileHandle
define PATH @"/Users/wangjingsai/Desktop/
1 . 读取文件
NSString *filePath = [PATH stringByAppendingPathComponent:@"test.txt"];
// 使用NSString/NSData直接读取
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSString *content = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; // data -> str
// [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]
2 . NSFileHandle
2 . 1 读文件
文件句柄,使用它对文件进行读取,写入,更改
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath]; // 以只读方式打开文件,不能往里面写入
fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath]; // 以只写方式打开文件,不能读取
fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:filePath]; // 以读写方式打开文件,即可读又可写
从文件开始读取
// 读10字节数据, 读完之后偏移10字节,再读时从10个字节以后开始读
data = [fileHandle readDataOfLength:10];
从当前偏移位置读取
data = [fileHandle readDataToEndOfFile]; // 从当前位置开始读到最后
重置偏移量
[fileHandle seekToFileOffset:16]; // 重置偏移量(即从什么地方开始读取)
2 . 2写文件
NSString *str5 = @"Oh~~, i love you more than i can say. 苍天不依人...";
data = [str5 dataUsingEncoding:NSUTF8StringEncoding]; // str --> data
// [fileHandle seekToFileOffset:0]; // 偏移量归0
[fileHandle truncateFileAtOffset:0]; // 清空文件
[fileHandle writeData:data]; // 把数据写进文件, 写一次那么文件偏移量就可以移动一次
[fileHandle synchronizeFile]; // 立即同步到磁盘
[fileHandle closeFile]; // 关闭文件
PList
1 . 读取
可以直接用字典(数组)内置的方法读取plist文件
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:PATH];
2 . 写入
把dict写入到指定路径下
NSString *filePath = [@"/Users/wangjingsai/Desktop/WeiZhenDir" stringByAppendingPathComponent:@"test.plist"];
dict = @{
@"weight" : @"1234567"
};
// NSArray *arr = @[@"one", @"two"];
// [arr writeToFile:(NSString *) atomically:(BOOL)];
// 第一个参数:路径
// 第二个参数:考虑线程安全问题
[dict writeToFile:filePath atomically:YES];
归档和解归档
// Foundation系统的类 NSArray NSDictionary 都默认可以归档和解归档
// 但是自定义的类要实现归档和解归档,就得遵守并实现协议
1 . 系统类NSDictionary的归档
NSDictionary *dict = @{
@"name" : @"刘德华",
@"age" : @58
};
NSString *filePath = [PATH stringByAppendingPathComponent:@"DeHua.txt"]; // 后缀不一定这样写
// NSKeyedArchiver归档类,负现把对象归档到本地文件
// 第一个参数:要归档的对象
// 第二个参数:归档到哪里(文件路径)
BOOL success = [NSKeyedArchiver archiveRootObject:dict toFile:filePath];
2 . 解归档
// 解归档
NSDictionary *dict2 = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
自定义对象归档
自定义对象要归档,就必须遵守协议并实现协议中的方法,对于对象中含有的对象(wife), 也要同样遵守协议并实现协议中的方法
Student.h
@interface Student : NSObject <NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic) NSInteger age;
@property (nonatomic) CGFloat score;
@property (nonatomic, retain) Wife *wife;
Student.m
// 归档的时候,此方法被调用
// BOOL success = [NSKeyedArchiver archiveRootObject:student toFile:filePath];
// 意味着对student对象归档,归档到filePath中
// 这个方法会被调用
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.name forKey:@"name"]; // 可以对self.name对象直接encode
[aCoder encodeInteger:self.age forKey:@"age"];
[aCoder encodeFloat:self.score forKey:@"score"]; // 这里面的key可以随意写,但是这儿key写成什么,解归档的时候要统一
[aCoder encodeObject:self.wife forKey:@"wife"]; // 这个时候会对self.wife对象进行归档,由于Wife是我们自定义的类,所以Wife也要遵守<NSCoding>协议并实现协议方法
}
// 解归档
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
self.score = [aDecoder decodeFloatForKey:@"score"];
self.wife = [aDecoder decodeObjectForKey:@"wife"];
}
return self;
}
Wife.h
@interface Wife : NSObject <NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic) float blood;
@end
Wife.m
// 归档的时候被调用
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeFloat:self.blood forKey:@"blood"];
}
// 解归档的时候被调用
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.blood = [aDecoder decodeFloatForKey:@"blood"];
}
return self;
}
6.NSUserDefaults
1,NSUserDefaults
NSUserDefaults是一种轻量化的数据持久化工具。适合保存诸如用户名,用户密码等信息。用NSUserDefaults进行读写都是非常方便的。
NSUserDefaults支持的数据格式有:NSNumber(Integer、Float、Double),NSString,NSDate,NSData,NSArray,NSDictionary,BOOL类型
NSUserDefaults在编程中是单例对象,实际是操作一个本地的plist文件(可在沙盒的Preferences文件夹中找到),存储的数据会先保存在内存中,等恰当时候再和本地plist文件进行同步。如果想及时同步信息,可以调用NSUserDefaults的synchronize方法
示例代码如下:
存数据
- (IBAction)save:(id)sender {
NSUserDefaults * userDefaults=[NSUserDefaults standardUserDefaults];
[userDefaults setDouble:3.141592653 forKey:@"pi"];
[userDefaults setInteger:12 forKey:@"age"];
[userDefaults setFloat:0.612 forKey:@"goldFenGe"];
[userDefaults setObject:@"是个字符串" forKey:@"str"];
[userDefaults setObject:@[@"a",@"b"] forKey:@"arr"];
[userDefaults setObject:@{@"name":@"yang"} forKey:@"dic"];
[userDefaults setObject:[NSDate date] forKey:@"date"];
[userDefaults setObject:[@"123" dataUsingEncoding:NSUTF8StringEncoding] forKey:@"data"];
[userDefaults setBool:YES forKey:@"bool"];
//把内存中的数据,和本地plist文件进行内容的同步。
[userDefaults synchronize];
}
取数据
- (IBAction)read:(id)sender {
NSUserDefaults * userDefaults=[NSUserDefaults standardUserDefaults];
NSLog(@"%f",[userDefaults doubleForKey:@"pi"]);
NSLog(@"%ld",[userDefaults integerForKey:@"age"]);
NSLog(@"%f",[userDefaults floatForKey:@"goldFenGe"]);
NSLog(@"%@",[userDefaults objectForKey:@"str"]);
NSLog(@"%@",[userDefaults objectForKey:@"arr"]);
NSLog(@"%@",[userDefaults objectForKey:@"dic"]);
NSLog(@"%@",[userDefaults objectForKey:@"date"]);
NSLog(@"%@",[userDefaults objectForKey:@"data"]);
NSLog(@"%d",[userDefaults boolForKey:@"bool"]);
}