在我的一个 cocoa 应用程序中,有一个方法可以对 sqlite 数据库的模式进行一些可能具有破坏性的操作,所以首先我们制作数据库的回滚副本,如果有错误,我们调用以下方法来替换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];
当发现目标路径中已有文件时,最接近此 barfs 的方法。
到目前为止基于响应的小更新:
必须有一些标准方式,这在传统上由 Cocoa 开发人员完成,以原子方式替换文件。NSFileManager 的各种“移动”方法并没有为此提供开箱即用的工具。此外,希望在此库中支持 10.5 及更高版本以及 iPhone OS 3+。