美文网首页
iOS - 沙盒机制

iOS - 沙盒机制

作者: ShIwEn9 | 来源:发表于2020-02-26 22:30 被阅读0次

    日常使用苹果的APP的时候,我们保存的数据大都保存在哪里呢?
    通常情况下,我们的数据多数保存在一个叫沙盒的结构中。所以了解苹果的沙盒存储机制是了解苹果数据存储的第一道门。

    一、概述:
    1. 介绍:应用沙盒机制:每个iOS应用都有自己的应用沙盒(文件系统目录),与其他文件系统隔离。每个应用必须在自己的沙盒里运行,其他应用不能访问该沙盒。
    2. 特点:
    • 每个应用程序的活动范围都限定在自己的沙盒里。
    • 不能随意跨越自己的沙盒去访问别的应用程序沙盒中的内容。
    • 在访问别人沙盒内的数据时需要访问权限。
    二、沙盒结构介绍:
    • 获取 软件的沙盒路径:
      • 通过NSHomeDirectory()获取沙盒路径并输出:
      NSLog(@"%@",NSHomeDirectory());
      
      • 通过NSSearchPathForDirectoriesInDomains()方法去查找路径:
        NSSearchPathForDirectoriesInDomains的参数说明:
        directory :表示需要查找的是哪一个文件夹,是一个枚举
        domainMask:搜索范围,是一个枚举类型;关于domainMask 看:NSSearchPathDomainMask详解
        expandTilde:是否扩展路径,YES->获取完整路径,一般为YES
        return:返回值为数组,这个数组中只有一个NSString类型元素,一般这个元素保存的就是查找的路径的唯一路径,所以直接取第一个就行了

    一般的沙盒的的根目录有三个文件夹,分别是:DocumentsLibrarytmp

    • Documents/:
      Documents一般用来保存APP中需要持久保存的文件和数据,例如游戏进度,绘图软件的绘图等,当iTunes 连接的时候会去备份和恢复Documents文件夹数据

    ⚠️注意:在此目录下不要保存从网络上下载的文件,否则app无法上架!

    获取 Documents/ 文件的路径:

    NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
    
    • Library/:
      Library目录下有两个子目录:Caches 和 Preferences
      获取 Library/ 的路径:
    NSString *path = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).lastObject;
    
    • Library/Caches:
      顾名思义,用来保存数据中的一些缓存的持久化数据,这些数据一般是体积较大,但并不是绝对需要的数据(多为网络请求的数据,如图片和视频等),这些数据需要用户自己去管理删除,当iTunes 连接的时候不会去备份和恢复数据
      获取 Library/Caches 路径
     NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject;
    
    • Library/Preferences:
      Preferences翻译过来就是偏好、偏爱的意思,所以多用来保存软件一些偏好设置(setting)当iTunes 连接的时候会去备份和恢复 Library/Preferences文件夹数据
      获取Library/Preferences的路径:
    NSString *path = NSSearchPathForDirectoriesInDomains(NSPreferencePanesDirectory, NSUserDomainMask, YES).lastObject;
    
    • tmp/:
      此目录保存应用程序运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份 tmp 目录
      获取 tmp/ 文件夹路径:
    NSString *path = NSTemporaryDirectory();
    
    三、文件操作
    1. 创建文件夹/目录
      通过 createDirectoryAtPath 方法实现:
    - (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(nullable NSDictionary<NSFileAttributeKey, id> *)attributes error:(NSError **)error;
    

    参数说明:
    path:文件夹/目录的路径
    withIntermediateDirectories:中间目录,如果为createIntermediates传递'NO',则在进行此调用时目录不能存在。为“createIntermediates”传递“YES”将创建任何必要的中间目录。如果创建了“path”中指定的所有目录并设置了属性,则此方法返回YES。,一般返回YES
    attributes:目录是用传递给“attributes”的字典指定的属性创建的。如果没有提供字典,则根据进程的umask创建目录。具体设置查看文章
    (Objective-C创建目录接口)[https://blog.csdn.net/wanganqi19920813/article/details/8849706]
    error:如果提供了错误参数,则会通过引用返回可呈现的NSError
    return:如果在操作的任何阶段发生故障,则此方法返回NO

    -(BOOL)createDir:(NSString *)fileName{
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString * path = [NSString stringWithFormat:@"%@/%@",documentsDirectory,fileName];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        BOOL isDir;
        if  (![fileManager fileExistsAtPath:path isDirectory:&isDir]) {//先判断目录是否存在,不存在才创建
        BOOL res=[fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil]; 
        return res;  
     } else return NO; 
    
    1. 创建文件
      通过 createFileAtPath:方法实现
    - (BOOL)createFileAtPath:(NSString *)path contents:(nullable NSData *)data attributes:(nullable NSDictionary<NSFileAttributeKey, id> *)attr
    

    参数介绍:
    path:用来指定要创建的文件
    data:用来指定文件中的数据
    attr:用来指定字典,一般设置为nil
    return:返回创建的结果
    当(NSData *)data和(NSDictionary *)attr都设置为nil时,创建出来的文件就是一个空文件。

    -(BOOL)createFile:(NSString *)path{  
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSString *testPath = [path stringByAppendingPathComponent:@"test.c"];//在传入的路径下创建test.c文件
        //通过data创建数据
        NSData *data=[@"Hello world" dataUsingEncoding:NSUTF8StringEncoding];
        BOOL res = [fileManager createFileAtPath:testPath contents:data attributes:nil];
        return res; 
    }  
    
    1. 写数据到文件
      通过 writeToFile: 方法实现
    - (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error
    

    参数说明:
    path:存储的文件夹路径
    atomically:如果为YES则保证文件的写入原子性,就是说会先创建一个临时文件,直到文件内容写入成功再导入到目标文件里,如果为NO,则直接写入目标文件里
    encoding:格式
    error:错误信息
    return:写入是否正确

    1. 读数据
      通过 stringWithContentsOfFile: 或者 initWithContentsOfFile: 方法实现
      参数和写入的差不多
    -(void)readFile:(NSString *)path{  
    //方法1:
        NSData * data = [NSData dataWithContentsOfFile:path];  
        NSString * content = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);  
    //方法2:    
        NSString * content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];  
        NSLog(@"文件读取成功: %@",content);  
    }  
    
    1. 查看是否有相关文件
      通过方法 isExecutableFileAtPath:
    - (BOOL)isExecutableFileAtPath:(NSString *)path
    
    1. 获取文件的属性:
    -(void)fileAttriutes:(NSString *)path{  
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:path error:nil];     
        NSArray *keys;  
        id key, value;  
        keys = [fileAttributes allKeys];  
        int count = [keys count];  
        for (int i = 0; i < count; i++)  
        {  
            key = [keys objectAtIndex: i];  //获取文件名
            value = [fileAttributes objectForKey: key];  //获取文件属性
        }  
    }  
    
    1. 根据路径删除文件
      通过方法 removeItemAtPath:
    -(BOOL)deleteFileByPath:(NSString *)path{  
        NSFileManager *fileManager = [NSFileManager defaultManager];
        
        BOOL res=[fileManager removeItemAtPath:path error:nil];  
        return res;      
    }  
    
    1. 根据文件名删除文件
    - (BOOL)deleteFileByName:(NSString *)name{
        NSFileManager *fileManager = [NSFileManager defaultManager];
        
        [fileManager removeItemAtPath:[self getLocalFilePath:fileName] error:nil];//getLocalFilePath方法在下面
    }
    
    1. 复制文件
      通过 copyItemAtPath: 方法实现
    +(BOOL)copyFile:(NSString *)path topath:(NSString *)topath
    {
        
        BOOL result = NO;
        NSError * error = nil;
        
        result = [[NSFileManager defaultManager]copyItemAtPath:path toPath:topath error:&error ];
        
        if (error){
            NSLog(@"copy失败:%@",[error localizedDescription]);
        }
        return result;
    }
    
    1. 根据文件名获取文件路径
    • 资源文件
    +(NSString *)getResourcesFile:(NSString *)fileName
    {
        return [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
    }
    
    • 普通文件
    +(NSString *)getLocalFilePath:(NSString *) fileName
    {
        NSString * path = [NSHomeDirectory() stringByAppendingPathComponent:@"/Documents"]
        return [NSString stringWithFormat:@"%@/%@",path,fileName];
    }
    
    1. 根据文件路径获取文件名称
    +(NSString *)getFileNameByPath:(NSString *)filepath
    {
        NSArray *array=[filepath componentsSeparatedByString:@"/"];
        if (array.count==0) return filepath;
        return [array objectAtIndex:array.count-1];
    }
    
    1. 根据路径获取该路径下所有目录
    +(NSArray *)getAllFileByName:(NSString *)path
    {
        NSFileManager *defaultManager = [NSFileManager defaultManager];
        NSArray *array = [defaultManager contentsOfDirectoryAtPath:path error:nil];
        return array;
    }
    
    1. 根据路径获取文件目录下所有文件
    +(NSArray *)getAllFloderByName:(NSString *)path
    {
        NSFileManager *fileManager = [NSFileManager defaultManager];
        
        NSArray * fileAndFloderArr = [self getAllFileByName:path];
        
        NSMutableArray *dirArray = [[NSMutableArray alloc] init];
        BOOL isDir = NO;
        //在上面那段程序中获得的fileList中列出文件夹名
        for (NSString * file in fileAndFloderArr){
            
            NSString *paths = [path stringByAppendingPathComponent:file];
            [fileManager fileExistsAtPath:paths isDirectory:(&isDir)];
            if (isDir) {
                [dirArray addObject:file];
            }
            isDir = NO;
        }
        return dirArray;
    }
    

    14.获取文件及目录的大小

    +(float)sizeOfDirectory:(NSString *)dir{
        NSDirectoryEnumerator *direnum = [[NSFileManager defaultManager] enumeratorAtPath:dir];
        NSString *pname;
        int64_t s=0;
        while (pname = [direnum nextObject]){
            //NSLog(@"pname   %@",pname);
            NSDictionary *currentdict=[direnum fileAttributes];
            NSString *filesize=[NSString stringWithFormat:@"%@",[currentdict objectForKey:NSFileSize]];
            NSString *filetype=[currentdict objectForKey:NSFileType];
            
            if([filetype isEqualToString:NSFileTypeDirectory]) continue;
            s=s+[filesize longLongValue];
        }
        return s*1.0;
    }
    
    1. 重命名文件或者目录
    +(BOOL)renameFileName:(NSString *)oldName toNewName:(NSString *)newName
    {
        
        BOOL result = NO;
        NSError * error = nil;
        result = [[NSFileManager defaultManager] moveItemAtPath:[kDSRoot stringByAppendingPathComponent:oldName] toPath:[kDSRoot stringByAppendingPathComponent:newName] error:&error];
        
        if (error){
            NSLog(@"重命名失败:%@",[error localizedDescription]);
        }
        
        return result;
    }
    
    1. 读取文件
    +(NSData *)readFileContent:(NSString *)filePath{
        
        return [[NSFileManager defaultManager] contentsAtPath:filePath];
    }
    
    1. 保存文件
    +(BOOL)saveToDirectory:(NSString *)path data:(NSData *)data name:(NSString *)newName
    
    {
        NSString * resultPath = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"/%@",newName]];
        return [[NSFileManager defaultManager] createFileAtPath:resultPath contents:data attributes:nil];
    }
    

    沙盒的介绍就到这里,如果喜欢不妨点个赞,如有错误或者疑问欢迎评论区留言,一起加油⛽️
    参考文章:
    iOS 开发之沙盒机制
    iOS之NSFilemanager文件管理(沙盒)

    相关文章

      网友评论

          本文标题:iOS - 沙盒机制

          本文链接:https://www.haomeiwen.com/subject/lmlichtx.html