OC沙盒导致文件不能通过NSFileManager读写问题

OC沙盒导致文件不能通过NSFileManager读写问题,第1张

在最近开发的项目中,有这样一项需求,我需要获得一个文件夹下的全部文件的文件名称,然后对每个文件进行一些处理。

查阅资料发现,可以通过NSFileManager进行 *** 作。于是我采用了如下代码解决问题。

(这段代码也是CV大法来的哦,原文链接:iOS 递归遍历文件夹及其子集下的所有文件_icefishlily的博客-CSDN博客_ios 递归遍历)

    NSFileManager * fileManger = [NSFileManager defaultManager];
    BOOL isDir = NO;
    BOOL isExist = [fileManger fileExistsAtPath:path isDirectory:&isDir];
    if (isExist) {
        if (isDir) {
            NSArray * dirArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
            NSString * subPath = nil;
            for (NSString * str in dirArray) {
                subPath  = [path stringByAppendingPathComponent:str];
                BOOL issubDir = NO;
                [fileManger fileExistsAtPath:subPath isDirectory:&issubDir];
                [self loadAllFileWithPath:subPath];
            }
        }else{
            NSString *fileName = [[path componentsSeparatedByString:@"/"] lastObject];
            if (![fileName hasSuffix:@".json"] && ![fileName hasPrefix:@".DS_Store"]) {
                [self splitFileName:fileName];
            }else{
                [self parseUserJson:fileName];
            }
        }
    }else{
        NSLog(@"this path is not exist!");
    }

可以看出,我这段代码的作用是是在参数path代表的文件夹路径下进行文件搜索,将除了json和.DS_store之外的文件进行splitFileName处理(这个是我自定义的处理文件名函数)。然后将json和.DS_store文件进行parseUserJson处理(这个是我自定义的处理用户文件代码)。

结果执行一看,处理文件处理了个寂寞,检查路径没写错(开发期间为了验证功能可行性我直接写的绝对路径)。无奈,只好打个断点康康了。

断在如下位置,得到反馈:

有问题,属实有问题。这里竟然是个nil,按理来说,就算是没文件也应该是个0 elements的数组,这里是个nil说明函数执行就有问题,我们传个error进去康康代码执行的正常不正常。

好了,果不其然。错误代码257,错误信息谜语人看不懂,百度一下,从这篇文章(NSCocoaErrorDomain错误码解析 - 简书)里得知 ,原来是权限问题导致的读取问题。

然后又开始了漫长了查询资料阶段,然后发现,OC其实是存在沙盒机制的,一个APP在运行时,只能在它沙盒范围下进行文件处理,沙盒外的文件一概不能碰。

(话说之前写的一个工程也有类似的绝对路径读写文件需求,却没遇到这个问题)

好吧,涨姿势了,那就看看沙盒路径在哪呗,一查发现,可以通过NSHomeDirectory方法来获取到沙盒所在的路径,一试,果不其然,在这里就可以读取到。

经过我的实验,发现在Xcode编译出来的可执行文件中,右键显示包内容,然后其下面的路径也能够正常访问(看了一下路径,应该是和上面方法获取到的沙盒路径不一样,怎么会事呢),就像这样:

真让人摸不着头脑,但是总算是解决了读取不到文件的问题。

然后呢,读取完了,得 *** 作文件了,光读不写非英雄也!开整。

这次的需求是把上面读取到的文件进行筛选,然后挑选一个粘贴到别的路径下。

目标路径是上面说的Xcode编译出来的可执行文件包里的另一个app包里的资源路径(很绕对不对,其实就是工程的资源里又个app包,替换其下的资源)。

至于复制方法呢,这里有两种思路:

其一是采用copyItemAtPath这个接口,将文件从原路径拷贝到目标路径。

这个接口可以这么调用

[[NSFileManager defaultManager] copyItemAtPath:path  toPath:targetPath  error:nil];

将文件从path拷贝到targetPath路径中。

!注意:这里的targetPath必须以文件名结尾而不是以文件夹名

不然就会这样。

516错误代码,回到上面的文章看一下,是 写错误(文件存在)

因为你指定的文件夹肯定是存在的,你要指定一个目标文件夹下不存在(不与已有文件名重复)的文件名,这样文件就会以你指定的名字复制到目标文件夹。

第二种方法呢,我们可以读取文件的内容,然后将其写入目标文件夹下的文件中。

这里就直接用writeToFile接口好了,就不多说了。

但是呢,我又失败了,没错,又失败了。

如下图所示的错误:

 513,老规矩,查一下,是 写错误(权限问题)

啊?能读不能写是吧。这咋办呢,还对读写的权限有区分。

其实到这里我已经失去耐心了,毕竟工期有限,不好耽误太多时间,还记得我上面说的之前的工程没有遇到绝对路径读取问题吗,我直接复制了一份那个工程,然后清空里面的代码,将这个工程代码粘贴进去,顺利的跑起来了,全写的包外绝对路径,既没读取权限问题,也没写权限问题。真是离天下之大谱。跑代码果然是玄学。

但是,这问题也不好扔在这不管了,万一以后遇到不能替换工程解决的情况呢,所以今天就来继续探索一下怎么解决。

找回之前的工程跑一下,嗯,错误代码513,还是原汁原味的权限问题。

猜测是仍旧是沙盒问题,毕竟一个APP发出来不能让你狂自定义写包内文件才合理。

所以我们的工程也不能渗透到资源下的包里写包里的文件,但是既然另一个工程不受影响,那就说明是可解的,我们去了解一下沙盒,看看有没有解决办法。

然后经过一番查资料和比对,发现原来sandBox是可以取消掉的。

在下图所示的地方

看见App SandBox右边那个叉没,按下这个按钮,万事皆休,啊不对,完美解决。

叉掉之后在之前的地方断一下再看。 

好耶,错误没了,对应文件夹下文件也复制出来了。

啊……原来我当时搞这么多,结果正确答案就这么一步啊。。。解决问题本来该轻松的时刻却感觉很😓,可能这就是程序员吧。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/993111.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存