创建文件夹、创建文件、文件夹里面创建文件
一.几种沙盒常用的存储方式
1. 项目中常用的NSUserDefaults存放的地址是:Library/Preferences,里面以bundleId为名的偏好设置plist文件里面;
Library/Preferences包含应用程序的偏好设置文件,您不应该直接创建偏好设置文件,而是应该使用NSUserDefaults类来取得和设置应用程序的偏好。
2. 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦;
3. 归档:因为间接(NSUserDefaults)或者直接操作使用plist文件,只能存储常用的类型, 而归档可以实现把自定义的对象存放在文件中。
二. 存取的方式
通常用fileManager写入的例如页面信息等大量缓存等存放地址是:Library/Caches; 写入的运行过程产生的如用户信息等需要持久化的数据,可以写入document。
NSUserDefaults直接写入后,是默认存放在系统偏好设置的plist文件(registerDefaults方法除外,它没有写入plist)。
fileManager写入:
1. 先创建路径(也就文件夹路径):
NSFileManager *fileM = [NSFileManager defaultManager];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"wgj01"];
if (![fileM fileExistsAtPath:documentsPath]) {
[fileM createDirectoryAtPath:documentsPath withIntermediateDirectories:YES attributes:nil error:nil];
}
2. 写入方式一:
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"w"];
NSDictionary *dict = @{@"w":@"wwww"};
[dict writeToFile:filePath atomically:YES];
这样写入之后,在NSCachesDirectory里面的wgj01文件夹中有一个w文件,因为没有后缀,所以存放格式为xml格式。
3. 写入方式二:
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"ws.plist"];
NSDictionary *dict = @{@"w":@"wwww"};
[dict writeToFile:filePath atomically:YES];
文件ws有后缀,写入的是plist格式。
3.1 针对3 的读取&修改方式:
//读取:
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"ws.plist"];
NSMutableDictionary *dataDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
NSLog(@"\n\n\n%@",dataDict);
//修改或添加:
[dataDict setObject:@"mmmmm" forKey:@"m"];
[dataDict writeToFile:filePath atomically:YES];
3.2 对于项目文件中的plist文件:
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"wgjTT" ofType:@"plist"];
和沙盒里面的plist文件(上面3.1)一样,对解析出来的字典或者数组进行增删改等操作,
但是,操作后,点击查看plist文件,发现没有变化,而,打印:
NSMutableDictionary *dataDictafter = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath1];
NSLog(@"\n\n\nTT0:\ndataDictafter:\n%@",dataDictafter);
发现,打印结果时改变后的结果。
猜测:应该是只写入了缓存,等程序重新运行,打印plist数据结果还是修改前的结果(plist并未有实质性的改变)。
4. 写入方式三:
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"wh"];
NSDictionary *dict = @{@"w":@"wwww"};
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
[fileM createFileAtPath:filePath contents:data attributes:nil];
这样,在wgj01文件夹下有一个wh文件,它里面的格式为:json格式。
eg.
{
"w" : "wwww"
}
4.1 针对4的读出方式:
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"wh"];
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSDictionary *object11 = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableContainers) error:nil];
NSLog(@"\n\n\n%@",object11); //读取成功
5. 若想要继续创建文件夹,用stringByAppendingPathComponent后面拼接文件夹名称 并且 用 if (![fileM fileExistsAtPath:documentsPath]) {
[fileM createDirectoryAtPath:documentsPath withIntermediateDirectories:YES attributes:nil error:nil];
}创建文件夹。
沙盒路径各目录用途:
Documents 目录:您应该将所有de应用程序数据文件写入到这个目录下。这个目录用于存储用户数据或其它应该定期备份的信息。
AppName.app 目录:这是应用程序的程序包目录,包含应用程序的本身。由于应用程序必须经过签名,所以您在运行时不能对这个目录中的内容进行修改,否则可能会使应用程序无法启动。
Library 目录:这个目录下有两个子目录:Caches 和 Preferences
Library/Preferences 目录:包含应用程序的偏好设置文件。您不应该直接创建偏好设置文件,而是应该使用NSUserDefaults类来取得和设置应用程序的偏好.
Library/Caches 目录:用于存放应用程序专用的支持文件,保存应用程序再次启动过程中需要的信息。
tmp 目录:这个目录用于存放临时文件,保存应用程序再次启动过程中不需要的信息。
1 应用程序包:包含所有资源文件和可执行文件
2 Documents:保存应用运行时生成的需要持久化的数据,iTunes会自动备份该目录
3 tmp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除,应用没有运行时,系统也可能会自动清理该目录下的文件,iTunes不会同步该目录,iPhone重启时该目录下的文件会丢失。
4 Libaray:存储程序的默认设置和其他状态信息,iTunes会自动备份该目录。
5 Libaray/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除,一般存放体积比较大,不是很重要的资源
6 Libaray/Preferences:保存应用的所有偏好设置,ios的Settings(设置)应用会在该目录中查找应用的设置信息,iTunes会自动备份该目录。
沙盒路径地址的获取:
1,获取家目录路径的函数:
NSString *homeDir = NSHomeDirectory();
2,获取Documents目录路径的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
3,获取Caches目录路径的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDir = [paths objectAtIndex:0];
4,获取tmp目录路径的方法:
NSString *tmpDir = NSTemporaryDirectory();
5,获取应用程序程序包中资源文件路径的方法:
例如获取程序包中一个图片资源(apple.png)路径的方法:
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@”apple” ofType:@”png”];
UIImage *appleImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
代码中的mainBundle类方法用于返回一个代表应用程序包的对象。
e.g.
NSString *Path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSLog(@"目录:%@",Path);
NSString *dataStr1 = @"testdata";
NSString *dataStr2 = @"wgjwgj";
NSString *dataStr3 = @"umeng";
NSData *data1 = [dataStr1 dataUsingEncoding:NSUTF8StringEncoding];
NSData *data2 = [dataStr2 dataUsingEncoding:NSUTF8StringEncoding];
NSData *data3 = [dataStr3 dataUsingEncoding:NSUTF8StringEncoding];
NSString *path1 = [Path stringByAppendingPathComponent:@"wgjTest1"];
NSString *path2 = [Path stringByAppendingPathComponent:@"wgjTest2"];
NSString *path4 = [Path stringByAppendingPathComponent:@"wgjjm"];
NSFileManager *fileManager1 = [NSFileManager defaultManager];
//创建文件夹
[fileManager1 createDirectoryAtPath:path4 withIntermediateDirectories:YES attributes:nil error:nil];
//创建文件
[fileManager1 createFileAtPath:path1 contents:data1 attributes:nil];
[fileManager1 createFileAtPath:path2 contents:data2 attributes:nil];
//文件夹里面创建文件
NSString *path5 = [path4 stringByAppendingPathComponent:@"wgj5"];
[fileManager1 createFileAtPath:path5 contents:data3 attributes:nil];
NSURL *url = [NSURL fileURLWithPath:Path isDirectory:YES];
//遍历url这个相应的目录下的文件和文件夹以及文件夹中的文件,得出文件夹/文件目录,和文件大小
NSDirectoryEnumerator *fileEnumerator = [fileManager1 enumeratorAtURL:url
includingPropertiesForKeys:@[NSFileSize]
options:NSDirectoryEnumerationSkipsHiddenFiles
errorHandler:NULL];
NSUInteger fileCount = 0;
NSUInteger totalSize = 0;
for (NSURL *fileURL in fileEnumerator) {
NSNumber *fileSize;
[fileURL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:NULL];
totalSize += fileSize.unsignedIntegerValue;
fileCount += 1;
}
YYModel的yy_modelEncodeWithCoder和yy_modelInitWithCoder
1. 当自己实现归档archive的时候,需要实现<NSCoding>协议encode和code方法,并且需要把类里面的所有属性在encode和code方法中全部罗列操作一遍,很是麻烦,所以就可以使用YYModel的归档;
2. YYModel实现归档主要点:
a. 把属性分为几种类型,它把int bool等数值类型都转为了NSNumber类型并使用encodeObject:forKey: 直接当成object处理。
b. 把类对象的结构直接映射拿了出来,并映射到YY自己自定义的结构,之后循环判断此类和父类一直向上找,取出所有的属性并操作赋值。此取出属性,包括了类所有父类的自定义属性。
c. 通过objc_property_attribute_t获取成员变量的类型,并通过字符判断具体类型返回类型枚举以供使用。
MJModel的mj_decode和mj_encode
1. 其实mj的encode原理和YY的差不多,只不过,mj只是利用的objc_property_t的runtime方法,没有自定义和系统类相似的结构做映射;也是循环类的诸多父类,找出所有的自定义属性。
2. 因为没有做结构体的映射,所以表面看起来稍微简单些。
3. 在encode的时候,也是把数值布尔等类型转化为NSNumber类型,进行encodeObject;具体做法是根据方法property_getAttributes,获取类型字符串然后截取,如果是q或者i等等数值类型,就归为NSNumber。
NSKeyedArchiver
- 对单个对象归档解挡
方式a. 归: NSData *arData = [NSKeyedArchiver archivedDataWithRootObject:model1];
[arData writeToFile:path1 atomically:YES];
解: NSData *resultData = [NSData dataWithContentsOfFile:path1];
id result = [NSKeyedUnarchiver unarchiveObjectWithData:resultData];
方式b. 归:BOOL isSuccess = [NSKeyedArchiver archiveRootObject:model1 toFile:path1];
解:id result = [NSKeyedUnarchiver unarchiveObjectWithFile:path1];
- 对多个对象归档解挡
1. 归: NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archive1 = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archive1 encodeObject:@"13223432342" forKey:@"111"];
[archive1 encodeObject:model forKey:@"222"];
[archive1 finishEncoding];
BOOL is1 = [data writeToFile:path1 atomically:YES];
解: NSData *data2 = [NSData dataWithContentsOfFile:path1];
NSKeyedUnarchiver *archive2 = [[NSKeyedUnarchiver alloc] initForReadingWithData:data2];
id result21 = [archive2 decodeObjectForKey:@"111"];
id result22 = [archive2 decodeObjectForKey:@"222"];
NSLog(@"resut21:%@\n result22:%@",result21,result22);
注意:多个对象initForWritingWithMutableData归档时,finishEncoding方法之后,不能在归档,再写encode会报错;所以这个和数据库不一样,也就不能在多个地方写入,只能一次性写入,如多次针对同路径文件写入,需要创建多次keyArchive,原来的文件内容会被清掉,只保存最近的写入内容。
单个对象归档也是一样,是直接清掉之前并写入新的信息。