10.18 ios系统沙盒机制 与 NSFileManager文件管理类的使用
1. Sandbox: IOS系统中文件管理的一种机制,指每一个应用程序内部,都只有下面安装目录下的三个文件下可以进行写文件操作。其他任何地方,都是只读的。注意在模拟器上可以在除下面三个文字下的其他地方写文件,因为模拟器上的文件说到底还是在Mac系统上,不是在真机的 IOS 系统上。
2. 安装目录(主目录); NSHomeDirectory()
|-- Documents: 保存用户文件,能够长久存在,即使系统更新或应用程序升级也不会改动。
|-- tmp: 存放临时文件
|-- Library/Caches: 能够存放一段时间,随着系统更新和应用程序升级,这个文件和tmp文件下的内容会自动被清除。
------
tmp目录: NSTemporaryDirectory() 方法直接获取tmp目录
获取Document, Caches目录: 按以下方式获取。
NSArray *array = NSSearchPathForDirectoriesIndomains( ,, ) 方法可以查找应用程序安装目录下的一些目录路径,
3. 可执行文件所在目录,可通过下面方式获取。
// 获取主包的对象
NSBundle *mainBundle =[NSBundle mainBundle];
// 获取主包所在目录,即可执行文件所在目录。
NSString *path = [mainBundle bundlePath];
// 在主包目录下找寻特定的文件,需要指定文件名和扩展名,没有扩展名可置为“”或nil
NSString *infoPath = [ mainBundle pathForResource : @“info” ofType: @“txt”];
-------
IOS 8 以前:mainBundle 目录也是在上面的安装目录下,但是在IOS 8 后,mainBundle目录就和安装目录不在一起了。
-------
nib 文件后缀:NextStep Interface Builder
Xcode 3 : 开发由两个独立开发工具一起进行, Xcode + Interface Builder : xib文件后缀
Xcode 4 : Xcode 集成了 Interface Builder 工具 : xib , 一个xib只能对应一个类的对象
Xcode 5~ :Xcode产生了storyBoard 工具, 一个storyBoard对应一个场景,可以有很多页面 和 类对象。
xib 文件编译完成后就变成了nib文件,
--------
//一、IOS系统上获取文件路径练习
//1. 获取当前应用安装目录: 该安装目录下包含三个文件,Document,Library,tmp
NSString *homePath = NSHomeDirectory();
NSLog(@"home: \n%@", homePath);
//2. 获取安装目录下的tmp目录
//直接获取
NSString *tmpPath1 = NSTemporaryDirectory();
NSLog(@"tmp1: \n%@", tmpPath1);
//通过上面获取的安装目录homePath获取
NSString *tmpPath2 = [homePath stringByAppendingPathComponent:@"tmp"];
NSLog(@"tmp2: \n%@", tmpPath2);
//3. 获取安装目录下的其他文件,如document,library文件下的caches文件,获取这些文件的路径没有像上面获取tmp文件路径那样有直接的方法 NSTemporaryDirectory()获取,而是需要用下面的方式获取
//通过上面获取的安装目录homePath来获取
NSString *docPath = [homePath stringByAppendingPathComponent:@"Documents"];
NSLog(@"docPath: \n%@", docPath);
//通过搜索的方式来获取,用该方法在IOS 系统上只能搜索 NSDocumentDirectory、NSLibraryDirectory、NSCachesDirectory目录。第二个参数表示是基于哪个目录去找,在IOS 程序中,该参数只能指定为NSUserDomainMask,表示基于应用程序的安装目录HomeDirectory去找。第三个参数表示是否要解开~符号,如果为NO,则获取的结果路径前面是~,如果为YES,会将该~号解开为第二个参数对应的目录路径。
NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(@"search array:\n%@", array);
//4.获取应用程序所在目录,注意,IOS 8以后应用程序和安装目录就不在一起了。通过主包类来获取
//获取主包对象
NSBundle *mainBundle = [NSBundle mainBundle];
//获取mainBundle的路径, 即应用程序所在目录路径
NSString *appPath = [mainBundle bundlePath];
NSLog(@"appPath: \n%@", appPath);
//获取主包中一个文件的路径
NSString *infoPath = [mainBundle pathForResource:@"info" ofType:@"txt"];
NSLog(@"infoPath: \n%@", infoPath);
--------
//OC文件管理练习,用到了NSFileManager类, 可以进行创建,删除,修改,移动,复制等一系列有关文件管理的操作
- (void)nsFileManagerTest
{
NSString *documentPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];//ios系统上面的文件路径是大小写敏感的,所以一定要记得区分大小写。
//获取NSFileManager的单例对象。
NSFileManager *fileManager = [NSFileManager defaultManager];
//注意以下所有方法中的路径参数中如果包含有~符号,必须使用该路径参数的stringByExpandingTildeInPath属性值,~号代表NSHomeDirectory()的返回值
//一、创建和删除项目
//1.创建文件,如果指定的文件已存在,将覆盖原有文件,前提是有权限这样做。如果指定位置有和其同名的文件夹,将创建失败
NSString *creatFilePath = [documentPath stringByAppendingString:@"/creatFile.txt"];
NSData *contents = [@"creat!!!!" dataUsingEncoding:NSUTF8StringEncoding];
//第二个参数表示文件内容,第三个参数设置文件属性,是一个字典对象
if([fileManager createFileAtPath:creatFilePath contents:contents attributes:nil]){
NSLog(@"file created !");
}else{
NSLog(@"file create failed !");
}
//2.创建文件夹,在指定的文件路径
NSString *creatDirPath = [documentPath stringByAppendingString:@"/dir1/dir2/dir3"];
NSError *error;
//下面方法的第二个参数表示是否创建第一个参数指定路径中包含的中间文件夹
if([fileManager createDirectoryAtPath:creatDirPath withIntermediateDirectories:YES attributes:nil error:&error]){
NSLog(@"dir created !");
}else{
NSLog(@"dir create failed !");
}
NSLog(@"%@", documentPath);
//3.创建文件夹,在指定的URL所表示的资源位置。
// - createDirectoryAtURL: withIntermediateDirectories: attributes: error:
//4.移除指定URL或文件路径位置上的项目,如果项目是个文件夹,将递归的删除其下面所有的文件和文件夹; 移除之前,该fileManager会询问其委托对象deleagte是否应该进行移除,如果返回YES或者委托对象没有实现相对应的方法,则进行移除,否则,不进行。如果移除过程中出错,该fileManager也会询问委托对象是否在错误之后继续进行移除。
// - removeItemAtURL: error:
// - removeItemAtPath: error:
//5.替换指定URL上的项目, backupItem参数是原始项目的备份,通过options可以选择是否保留该备份。
// - replaceItemAtURL: withItemAtURL: backupItem: options: resultingItemURL: error:
//二、移动和复制文件
//1.复制文件, dstPath中必须包含srcPath指定被复制后的文件或文件夹的名字,复制时,必须具有对srcPath指定项目的可读权和对dstPath的父目录的可写权。如果srcPath是个文件夹,将其整个内容复制,包括隐藏文件(mac上面以.开头的文件名),如果dstpath早已存在,复制将不会进行,同时返回一个错误信息。复制前,fileManager同样会询问其委托对象delegate是否要进行复制,若为YES,或delegate没有实现相应的方法,就进行复制;若复制过程出错,也会询问delegate是否在错误后进行复制,来确定接下来的行为。该方法也有相对应的URL版本。
// - copyItemAtPath: toPath: error:
if ([fileManager copyItemAtPath:creatFilePath toPath:[creatDirPath stringByAppendingString:@"/copyCreatFile"] error:&error]) {
NSLog(@"copy success!");
}else
NSLog(@"error:\n%@", error);
//2. 移动文件,和复制文件一样,只是是剪切文件。同样有URL版本。
if ([fileManager moveItemAtPath:creatFilePath toPath:[creatDirPath stringByAppendingString:@"/moveCreatFile"] error:nil]) {
NSLog(@"move success!");
}
//三、判断文件是否存在和其权限
//1.判断文件是否存在
if([fileManager fileExistsAtPath:creatFilePath]){
NSLog(@"creatFile exist !");
}
//2.判断文件是否存在,以及该文件是否是一个文件夹
BOOL isDir;
if([fileManager fileExistsAtPath:creatDirPath isDirectory:&isDir]){
if(isDir)
NSLog(@"creatDir exist !");
}
//3.文件是否可读
NSLog(@"read ? : %d", [fileManager isReadableFileAtPath:creatFilePath]);
//4.文件是否可写
NSLog(@"write ? : %d", [fileManager isWritableFileAtPath:creatFilePath]);
//5.文件是否可执行
NSLog(@"executable ? : %d", [fileManager isExecutableFileAtPath:creatFilePath]);
//6.文件是否可删除
NSLog(@"delete ? : %d", [fileManager isDeletableFileAtPath:creatFilePath]);
//由上面可看出,默认生成的文件权限是可读写,可删除的
//四、获取和设置文件属性
//1.获取文件属性,返回对象为字典对象
NSDictionary *fileAttrDic = [fileManager attributesOfItemAtPath:creatFilePath error:&error];
NSLog(@"attribute: \n%@", fileAttrDic);
//2.设置文件属性
// - setAttributes: ofItemAtPath: error:
//五、获取文件内容
//1.获取指定文件夹下的所有文件或文件夹的名字,存放在数组中, 不进行递归的枚举,包括隐藏文件,但是不会包含.和..目录和以“._”开头的文件;打印数组时,用“”包围的表示是文件,没有“”的表示文件夹。如果指定的路径不是一个文件夹,将返回nil,同时返回一个错误信息。
NSArray *fileArray = [fileManager contentsOfDirectoryAtPath:documentPath error:&error];
if(fileArray)
NSLog(@"fileArray: \n%@", fileArray);
else
NSLog(@"error: %@", error);
//2.获取遍历指定文件夹下文件的枚举器。该枚举器将枚举以该文件夹为根的文件树上的所有文件及文件夹。包括隐藏文件。但是对于符号链接,并不会分解该链接。
NSLog(@"---Enum---");
NSDirectoryEnumerator *dirEnum = [fileManager enumeratorAtPath:documentPath];
NSString *subFile;
//获取一个文件树下所有的txt类型文件
NSMutableArray *txtFileArray = [[NSMutableArray alloc] init];
while(subFile = [dirEnum nextObject]){
if([subFile.pathExtension isEqualToString:@"txt"])
[txtFileArray addObject:subFile];
}
NSLog(@"txtFileArray:\n%@", txtFileArray);
//3.一次性获取一个文件夹树下的所有文件和文件夹,没有上面的枚举器的可控性和效率。对于符号链接,一样会遍历其所指向的文件。下面两个方法都实现同样的功能,但是一个能获取错误信息,一个无法获取错误信息。
NSArray *subFileArray = [fileManager subpathsAtPath:documentPath];
NSLog(@"%@", subFileArray);
NSLog(@"----------");
NSArray *subFileAtDirArray = [fileManager subpathsOfDirectoryAtPath:documentPath error:&error];
NSLog(@"%@",subFileAtDirArray);
}

浙公网安备 33010602011771号