在我的cocoa应用程序中,有一种方法可以对sqlite数据库的模式执行一些可能具有破坏性的操作,因此首先我们制作数据库的回滚副本,如果有错误,我们调用以下方法用rollback文件替换db文件。请注意,我绝对希望db文件替换为回滚!
- (BOOL)restoreDatabaseFromFileAtPath:(NSString *)backupPath error:(NSError **)error {
NSFileManager *fm = [NSFileManager defaultManager];
// get the db paths
NSString *databasePath = [sharedManager pathToDatabase];
// insist that the two files be present
NSAssert1([fm fileExistsAtPath:databasePath], @"no db file at %@", databasePath);
NSAssert1([fm fileExistsAtPath:backupPath], @"no backup db file at %@", backupPath);
// remove the original to make way for the backup
NSLog(@"removing the file at the primary database path...");
if ([fm removeItemAtPath:databasePath error:error]) {
// now move the backup to the original location
NSLog(@"moving the backup file into the primary database path...");
if ([fm moveItemAtPath:backupPath toPath:databasePath error:error]) {
return YES;
}
}
[self presentError:error]; // at this point we're in real trouble
return NO;
}
显示的代码确实有效,但它可能非常具有破坏性并且不完全是原子的。我真正想做的是我想象的东西存在,但我找不到在NSFileManager的API中做到这一点的方法,如:
Bool success = [fm moveFileAtPath:backupPath toPath:databasePath overwriteDestination:YESPLZ error:&error];
当发现目标路径上已存在文件时,最接近此barf的方法。
基于目前为止的回复的小更新:
传统上Cocoa开发者必须采用一些标准方式来原子地替换文件。 NSFileManager的各种“移动”方法不提供开箱即用的功能。此外,希望在此lib以及iPhone OS 3 +中支持10.5及更高版本。
答案 0 :(得分:9)
NSFileManager
的{{1}}怎么样?
答案 1 :(得分:3)
C级FSMoveObjectSync / FSMoveObjectAsync功能可能有所帮助。这些函数采用一组选项,其中包括flag to overwrite the destination,kFSFileOperationOverwrite
等。
答案 2 :(得分:1)
我建议FSExchangeObjects
,PBExchangeObjectsSync
或PBExchangeObjectsAsync
函数,因为它们实际上原子地交换了两个文件的内容。
该功能允许程序 实施“安全保存”操作 创造和写作一个全新的 归档并交换内容。
交换后,访问路径 将引用相反文件的数据 (也就是说,它是相同的数据 最初提到的,现在是其中的一部分 另一个文件)。
适用于Mac OS X v10.0及更高版本。