14

Using the line below,

[fileManager copyItemAtPath:sourcePath toPath:targetPath error:&error];

We can copy a folder but if the folder already exists it throws an exception "File Exists". In order to overwrite a single file, we can achieve it through the following lines:

NSData *myData = [NSData dataWithContentsOfURL:FileURL]; /fetch single file
[myData writeToFile:targetPath atomically:YES];

But I want to copy an already existing folder i.e, overwrite.

Edit : Simple Possibility , I can remove the items before copying them.

Please suggest any more possibilities.

shim
  • 9,289
  • 12
  • 69
  • 108
itechnician
  • 1,645
  • 1
  • 14
  • 24
  • 2
    please check this :- http://stackoverflow.com/questions/6137423/how-to-overwrite-a-file-with-nsfilemanager-when-copying – Nitin Gohel Dec 28 '13 at 05:42

4 Answers4

11

The default behavior of NSFileManager method is to throw an exception/error "File Exists." when the file exists. But still if you want to overwrite using NSFileManager then it provides one api for that which is mentioned below replaceItemAtURL as well in first solution:-

Also there are three solutions to achieve that

First Solution

[filemanger replaceItemAtURL:url1 
               withItemAtURL:url2
              backupItemName:@"/Users/XYZ/Desktop/test.xml"
                     options:NSFileManagerItemReplacementUsingNewMetadataOnly 
            resultingItemURL:nil error:nil];

Using the above API you can overwrite the file contents. But before that you have to take the backup of your source path in your temporary directory.

Second Solution

Already you have mentioned in your question using NSData writeToUrl.

Third Solution

trojanfoe has mentioned in their answer. i.e. remove the item being overwritten beforehand.

Community
  • 1
  • 1
Hussain Shabbir
  • 14,801
  • 5
  • 40
  • 56
9

I would like to add one more using delegate, in order to override files with copyItemAtPath (NSFileManager) function use:

[[NSFileManager defaultManager] setDelegate:self];
[[NSFileManager defaultManager] copyItemAtPath:fileOrigin toPath:fileDestin error:&error];

and implement the delegates optional function:

 - (BOOL)fileManager:(NSFileManager *)fileManager shouldProceedAfterError:(NSError *)error copyingItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath{
    if ([error code] == NSFileWriteFileExistsError) //error code for: The operation couldn’t be completed. File exists
        return YES;
    else
        return NO;
}
Retro
  • 3,985
  • 2
  • 17
  • 41
3

Remove the item first, with:

[fileManager removeItemAtPath:targetPath error:NULL];

(i.e. ignoring any error)

trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • Thanks for your response . For copying my folder it consumes around 10 secs in device.Then, here in my case , If I delete the same , then Operation time will be doubled. – itechnician Dec 19 '13 at 14:16
  • -1: Why would you ignore the error? What if you don't have permission to remove the item? At the very least it should be logged to the console. – Craig Otis Dec 19 '13 at 14:17
  • @CraigOtis It will be caught by the next line of code (provided by the OP). – trojanfoe Dec 19 '13 at 14:23
  • @itechnician Are you sure it will *double* the time taken? I very much doubt that. – trojanfoe Dec 19 '13 at 14:27
  • @trojanfoe Accurately it wont take 2x (Approx 1.7~~1.98x time) time But I am sure that it will take less time (Approx 1.2~~1.4x time) incase it gets overwritten. Thanks again for your consideration – itechnician Dec 20 '13 at 05:21
  • Well, perhaps you could copy your original folder to a place besides the folder to be replaced, then rename both folders (effectively swapping them), the unlink the old, replaced folder.. I wonder if that would be faster? – nielsbot Dec 29 '13 at 22:16
  • Another option would be to recursively copy from source to destination only replacing outdated files. Maybe this would be faster? You will have to experiment. – nielsbot Dec 29 '13 at 22:17
0
    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
        [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
Darshit Shah
  • 2,366
  • 26
  • 33