iOS-(移动/复制)并合并文件夹、

【前言】

开发中遇到两个需求,是NSFileManager文件操作。
我有一个包含文件和子文件夹的A文件夹,我想将其复制到文件系统中的B文件夹下。在B中,可能已存在同名文件夹/文件,该文件夹也可能包含文件和文件夹。

【需求一】
我想用我A文件夹下所有文件移动到B文件夹下面,如果它们具有相同的名称,覆盖并替换B里面的同名文件,而B其余文件都不会受到影响。
【需求二】
我想用我A文件夹下所有文件复制到B文件夹下面,如果它们具有相同的名称,覆盖并替换B里面的同名文件,而B其余文件都不会受到影响。

【移动并合并文件】

根据需求如下文件操作简图:

Afolder
   |
   - file1
   - subfolder
       - file2

Bfolder
   |
   - file3
   - subfolder
       - file2
       - file4

resultfolder
   |
   - file1
   - file3
   - subfolder
       - file2      <-- version from Afolder
       - file4

代码如下:


- (void)mergeContentsOfPath:(NSString *)srcDir intoPath:(NSString *)dstDir error:(NSError**)err {

    NSLog(@"- mergeContentsOfPath: %@\n intoPath: %@", srcDir, dstDir);

    NSFileManager *fm = [NSFileManager defaultManager];
    NSDirectoryEnumerator *srcDirEnum = [fm enumeratorAtPath:srcDir];
    NSString *subPath;
    while ((subPath = [srcDirEnum nextObject])) {

        NSLog(@" subPath: %@", subPath);
        NSString *srcFullPath =  [srcDir stringByAppendingPathComponent:subPath];
        NSString *potentialDstPath = [dstDir stringByAppendingPathComponent:subPath];

        // Need to also check if file exists because if it doesn't, value of `isDirectory` is undefined.
        BOOL isDirectory = ([[NSFileManager defaultManager] fileExistsAtPath:srcFullPath isDirectory:&isDirectory] && isDirectory);

        // Create directory, or delete existing file and move file to destination
        if (isDirectory) {
            NSLog(@"   create directory");
            [fm createDirectoryAtPath:potentialDstPath withIntermediateDirectories:YES attributes:nil error:err];
            if (err && *err) {
                NSLog(@"ERROR: %@", *err);
                return;
            }
        }
        else {
            if ([fm fileExistsAtPath:potentialDstPath]) {
                NSLog(@"   removeItemAtPath");
                [fm removeItemAtPath:potentialDstPath error:err];
                if (err && *err) {
                    NSLog(@"ERROR: %@", *err);
                    return;
                }
            }

            NSLog(@"   moveItemAtPath");
            [fm moveItemAtPath:srcFullPath toPath:potentialDstPath error:err];
            if (err && *err) {
                NSLog(@"ERROR: %@", *err);
                return;
            }
        }
    }
}

【复制并合并文件】

关于如何判定全部复制成功呢?我这边通过谓词和数组对比来实现。
通过遍历两个文件夹,得到所有文件名称,进行数组去重即可。

typedef void(^resultBackBlock)(BOOL isSucess);

- (void)viewDidLoad {
    [super viewDidLoad];
 
    NSString * documentDir  =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
    NSString *oldPicPath =  [documentDir stringByAppendingPathComponent:@"AImageIcon"];
    NSString *newPicPath = [documentDir stringByAppendingPathComponent:@"BImageIcon"];

    //图片复制并合并
    [self copyFileFromPath:oldPicPath toPath:newPicPath complete:^(BOOL isSucess) {
        if (isSucess) {  complete(YES); return; }else{ complete(NO); return; }
    } ];
}

// 复制并合并文件夹
-(void)copyFileFromPath:(NSString *)sourcePath
                 toPath:(NSString *)toPath
               complete:(resultBackBlock)complete{

    // 1、得到文件路径
    NSFileManager *fileManager = [[NSFileManager alloc] init];
    NSArray* arraySor = [fileManager contentsOfDirectoryAtPath:sourcePath error:nil];

    if (arraySor.count == 0 ) { complete(YES); return; }
        
    // 2、遍历并复制文件到新文件夹
    for(int i = 0; i<[arraySor count]; i++){
        
        NSString *fullPath = [sourcePath stringByAppendingPathComponent:[arraySor objectAtIndex:i]];
        NSString *fullToPath = [toPath stringByAppendingPathComponent:[arraySor objectAtIndex:i]];
 
        //判断是不是文件夹
        BOOL isFolder = NO;
        //判断是不是存在路径 并且是不是文件夹
        BOOL isExist = [fileManager fileExistsAtPath:fullPath isDirectory:&isFolder];

        if (isExist){
            NSError *err = nil;
            [[NSFileManager defaultManager] copyItemAtPath:fullPath toPath:fullToPath error:&err];
            if (err!=nil) {  NSLog(@"===%@===%@===错误日志", err, [err userInfo]);}
            if (isFolder){ [self copyFileFromPath:fullPath toPath:fullToPath complete:^(BOOL isSucess) { }]; }
        }
    }
    
    // 3、判断一个数组是否包含另一个数组的所有元素,谓词。
    NSArray* arrayTo = [fileManager contentsOfDirectoryAtPath:toPath error:nil];
    NSArray * filterList = [arraySor filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"NOT (SELF IN %@)",arrayTo]];
    if (filterList.count == 0) { complete(YES); return; }else{  complete(NO); return; }
  
}

你可能感兴趣的:(iOS-(移动/复制)并合并文件夹、)