如何在复制时用NSFileManager覆盖文件?

我正在使用这种方法来复制文件:

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

我想覆盖已存在的文件。 此方法的默认行为是引发exception/错误“File Exists”。 当文件存在时。 没有选项可以指定它应该覆盖。

那么这样做最安全的方法是什么?

我会先检查文件是否存在,然后删除它,然后尝试复制? 这有一个危险,就是应用程序或设备在文件被删除后的纳秒内closures,但是新文件没有被复制到那个地方。 那么什么都没有

也许我将不得不先改变新文件的名称,然后删除旧的,然后重新更改新的名称? 同样的问题。 如果在这个纳秒内应用程序或设备closures,重命名不会发生?

你会想在这种情况下做一个primefaces保存 ,最好通过使用NSDataNSStringwriteToFile:atomically:方法(及其变体)来实现:

 NSData *myData = ...; //fetched from somewhere [myData writeToFile:targetPath atomically:YES]; 

或者对于一个NSString

 NSString *myString = ...; NSError *err = nil; [myString writeToFile:targetPath atomically:YES encoding:NSUTF8StringEncoding error:&err]; if(err != nil) { //we have an error. } 

如果你不能/不想保留内存中的文件内容,但需要按照其他build议中的说明进行primefaces重写,则可以先将原始文件复制到临时目录中以获得唯一path(Apple的文档build议使用临时目录),然后使用NSFileManager的

-replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:

根据参考文档,这种方法“以确保不发生数据丢失的方式replace指定URL处的项目内容”。 (来自参考文件)。 需要将原始文件复制到临时目录,因为此方法会移动原始文件。 这里是关于-replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:的NSFileManager参考文档-replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:

检测文件存在错误,删除目标文件并再次复制。

Swift 2.0中的示例代码:

 class MainWindowController: NSFileManagerDelegate { let fileManager = NSFileManager() override func windowDidLoad() { super.windowDidLoad() fileManager.delegate = self do { try fileManager.copyItemAtPath(srcPath, toPath: dstPath) } catch { print("File already exists at \'\(srcPath)\':\n\((error as NSError).description)") } } func fileManager(fileManager: NSFileManager, shouldProceedAfterError error: NSError, copyingItemAtPath srcPath: String, toPath dstPath: String) -> Bool { if error.code == NSFileWriteFileExistsError { do { try fileManager.removeItemAtPath(dstPath) print("Existing file deleted.") } catch { print("Failed to delete existing file:\n\((error as NSError).description)") } do { try fileManager.copyItemAtPath(srcPath, toPath: dstPath) print("File saved.") } catch { print("File not saved:\n\((error as NSError).description)") } return true } else { return false } } } 

为了覆盖文件,我更喜欢

 NSData *imgDta = UIImageJPEGRepresentation(tImg, 1.0); [imgDta writeToFile:targetPath options:NSDataWritingFileProtectionNone error:&err]; 

在循环中删除和复制文件有时无法按预期工作

我认为你所规定的纳秒的可能性是微弱的。 所以坚持第一种方法去除现有文件并复制新文件。

我想你在找什么是NSFileManagerDelegate协议方法:

 - (BOOL)fileManager:(NSFileManager *)fileManager shouldProceedAfterError:(NSError *)error copyingItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath; 

从这种方法,你可以决定如何处理现有的文件(重命名/删除),然后继续进行复制。

我知道这是一个重量级,但它确实为我工作:

 task = Process() task.launchPath = "/bin/cp" task.arguments = [srcPath, dstPath] task.launch() task.waitUntilExit() 

有时性能不是问题,我们只需要一些简单的工作。