de. de. -4 years ago 150
iOS Question

Merge folders with NSFileManager, overwrite only existing files

Basically I am looking for a way to merge two folder in the filesystem with the cocoa API:

I have a folder containing files and sub-folders, which I want to copy to a different location in the filesystem.

At my destination path, an equally-named folder already exists, which may contain files and folders as well.

Now I want to overwrite existing files inside my destination folder (or its subfolders) with the new content of my source folder if they have the same name.

All the rest of the files I want to leave untouched.

sourcefolder
|
- file1
- subfolder
- file2


destinationfolder
|
- file3
- subfolder
- file2
- file4


resultingfolder
|
- file1
- file3
- subfolder
- file2 <-- version from source folder
- file4


How can I do that?
Thanks a lot for your help!

Answer Source

I searched everywhere but found nothing. So I came up with my own solution, utilizing NSDirectoryEnumerator. This should work the diagram (overriding old files). Hope it helps.

- (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;
            }
        }
    }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download