replaceItemAtURL: 方法在某些情况下无法删除原始移动文件
The replaceItemAtURL: method fails to remove original moved files in some cases
我正在使用 NSFileManager 的 replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:
方法移动 sqlite 文件,以防使用 replacePersistentStoreAtURL:destinationOptions:withPersistentStoreFromURL:sourceOptions:storeType:error:
方法移动失败。该文件包含三个组件文件 - 一个以 .sqlite 结尾,一个以 .sqlite-wal 结尾,一个以 .sqlite-shm 结尾。所有文件都使用 replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:
方法正确地替换了现有的对应文件;但是,实际上只有移动的 .sqlite 文件从其原始位置删除。 .sqlite-wal 和 .sqlite-shm 文件确实会根据需要进行替换,但似乎它们实际上是被复制而不是被移动,因为这两个原始文件在它们恭敬的成功 replacePersistentStoreAtURL:destinationOptions:withPersistentStoreFromURL:sourceOptions:storeType:error:
操作结束时仍然存在.一切都发生在同一卷中,因此似乎没有理由制作副本。谁能帮我弄清楚为什么会这样?
这是代码。稍后记录的状态消息显示为:
Successfully replaced SQLITE file. SQLITE file does NOT still exist in
original location. Successfully replaced WAL file. WAL file DOES still
exist in original location. Successfully replaced SHM file. SHM file
DOES still exist in original location.
- (void)moveSqliteFileFromMigrateStorePathToFinalStorePathWithCompletionHandler:(void(^)(NSURL * migrateStoreURL,NSString * statusMessage,BOOL actuallyMovedFiles,BOOL movingHudIsRunning))handler {
__block NSString *statusMessage = nil;
__block BOOL actuallyMovedFiles = NO;
__block BOOL hudIsRunning = NO;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *applicationDocumentsDirectory = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *migrateStorePath = [applicationDocumentsDirectory stringByAppendingPathComponent:@"MyAppData.sqlite"];
NSURL *migrateStoreURL = [NSURL fileURLWithPath:migrateStorePath];
NSURL *finalStoreURL = [CoreDataController desiredFinalStoreURL];
NSString *finalStorePath = finalStoreURL.path;
NSString *fromWalPath = [migrateStorePath stringByAppendingString:@"-wal"];
NSString *fromShmPath = [migrateStorePath stringByAppendingString:@"-shm"];
BOOL walFileExists = [NSFileManager.defaultManager fileExistsAtPath:fromWalPath];
BOOL shmFileExists = [NSFileManager.defaultManager fileExistsAtPath:fromShmPath];
BOOL sqliteFileExists = [NSFileManager.defaultManager fileExistsAtPath:migrateStorePath];
if (sqliteFileExists || shmFileExists || walFileExists) {
[SVProgressHUD setForegroundColor:CPS_DARK_BLUE_COLOR];
[SVProgressHUD showWithStatus:NSLocalizedString(@"My App is updating. This one-time operation may take several minutes.",@"")];
hudIsRunning = YES;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (sqliteFileExists) {
BOOL finalStorePathFileExists = [NSFileManager.defaultManager fileExistsAtPath:finalStorePath];
NSError * sqliteMoveError = nil;
BOOL successfulSqliteMove = NO;
BOOL replacingSqliteFile = NO;
if (finalStorePathFileExists) {
replacingSqliteFile = YES;
NSURL *migrateStoreURL = [NSURL fileURLWithPath:migrateStorePath];
NSURL *finalStoreURL = [NSURL fileURLWithPath:finalStorePath];
successfulSqliteMove = [[NSFileManager defaultManager] replaceItemAtURL:finalStoreURL withItemAtURL:migrateStoreURL backupItemName:@"sqliteBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&sqliteMoveError];//NSFileManagerItemReplacementUsingNewMetadataOnly
}
else {
successfulSqliteMove = [[NSFileManager defaultManager] moveItemAtPath:migrateStorePath toPath:finalStorePath error:&sqliteMoveError];
}
if (sqliteMoveError) {
DLog(@"The error for the SQLITE move: %@",sqliteMoveError.localizedDescription);
}
if (successfulSqliteMove) {
actuallyMovedFiles = YES;
if([NSFileManager.defaultManager fileExistsAtPath:migrateStorePath]) {
statusMessage = replacingSqliteFile?NSLocalizedString(@"Successfully replaced SQLITE file. SQLITE file DOES still exist in original location.", @""):NSLocalizedString(@"Successfully moved SQLITE file. SQLITE file DOES still exist in original location.", @"");
}
else {
statusMessage = replacingSqliteFile?NSLocalizedString(@"Successfully replaced SQLITE file. SQLITE file does NOT still exist in original location.", @""):NSLocalizedString(@"Successfully moved SQLITE file. SQLITE file does NOT still exist in original location.", @"");
}
}
else {
statusMessage = replacingSqliteFile?[NSString stringWithFormat:@"%@ (%@). ",NSLocalizedString(@"Failed to replace SQLITE file", @""),sqliteMoveError.localizedDescription]:[NSString stringWithFormat:@"%@ (%@). ",NSLocalizedString(@"Failed to move SQLITE file", @""),sqliteMoveError.localizedDescription];
}
}
else {
statusMessage = NSLocalizedString(@"No SQLITE file to move.", @"");
}
if (walFileExists) {
NSString *toWalPath = [finalStorePath stringByAppendingString:@"-wal"];
BOOL toWalFileExists = [NSFileManager.defaultManager fileExistsAtPath:toWalPath];
NSError * walMoveError = nil;
BOOL successfulWalMove = NO;
BOOL replacingWalFile = NO;
if (toWalFileExists) {
replacingWalFile = YES;
NSURL *fromWalURL = [NSURL fileURLWithPath:fromWalPath];
NSURL *toWalURL = [NSURL fileURLWithPath:toWalPath];
//successfulWalMove = [[NSFileManager defaultManager] replaceItemAtURL:fromWalURL withItemAtURL:toWalURL backupItemName:@"walBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&walMoveError];
//THE ABOVE CODE WAS WRONG, WHICH WAS WHAT WAS CAUSING THE ISSUE
successfulWalMove = [[NSFileManager defaultManager] replaceItemAtURL:toWalURL withItemAtURL:fromWalURL backupItemName:@"walBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&walMoveError];
}
else {
successfulWalMove = [[NSFileManager defaultManager] moveItemAtPath:fromWalPath toPath:toWalPath error:&walMoveError];
}
if (walMoveError) {
DLog(@"The error for the WAL move: %@",walMoveError.localizedDescription);
}
if (successfulWalMove) {
actuallyMovedFiles = YES;
if([NSFileManager.defaultManager fileExistsAtPath:fromWalPath]) {
statusMessage = replacingWalFile?[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully replaced WAL file. WAL file DOES still exist in original location.", @"")]:[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully moved WAL file. WAL file DOES still exist in original location.", @"")];
}
else {
statusMessage = replacingWalFile?[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully replaced WAL file. WAL file does NOT still exist in original location.", @"")]:[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully moved WAL file. WAL file does NOT still exist in original location.", @"")];
}
}
else {
statusMessage = replacingWalFile?[NSString stringWithFormat:@"%@ %@ (%@). ",statusMessage,NSLocalizedString(@"Failed to replace WAL file", @""),walMoveError.localizedDescription]:[NSString stringWithFormat:@"%@ %@ (%@). ",statusMessage,NSLocalizedString(@"Failed to move WAL file", @""),walMoveError.localizedDescription];
}
}
else {
statusMessage = NSLocalizedString(@"No WAL file to move.", @"");
}
if (shmFileExists) {
NSString *toShmPath = [finalStorePath stringByAppendingString:@"-shm"];
BOOL toShmFileExists = [NSFileManager.defaultManager fileExistsAtPath:toShmPath];
NSError * shmMoveError = nil;
BOOL successfulShmMove = NO;
BOOL replacingShmFile = NO;
if (toShmFileExists) {
replacingShmFile = YES;
NSURL *fromShmURL = [NSURL fileURLWithPath:fromShmPath];
NSURL *toShmURL = [NSURL fileURLWithPath:toShmPath];
//successfulShmMove = [[NSFileManager defaultManager] replaceItemAtURL:fromShmURL withItemAtURL:toShmURL backupItemName:@"shmBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&shmMoveError];
//THE ABOVE CODE WAS WRONG, WHICH WAS WHAT WAS CAUSING THE ISSUE
successfulShmMove = [[NSFileManager defaultManager] replaceItemAtURL:toShmURL withItemAtURL:fromShmURL backupItemName:@"shmBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&shmMoveError];
}
else {
successfulShmMove = [[NSFileManager defaultManager] moveItemAtPath:fromShmPath toPath:toShmPath error:&shmMoveError];
}
if (shmMoveError) {
DLog(@"The error for the SHM move: %@",shmMoveError.localizedDescription);
}
if (successfulShmMove) {
actuallyMovedFiles = YES;
if([NSFileManager.defaultManager fileExistsAtPath:fromWalPath]) {
statusMessage = replacingShmFile?[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully replaced SHM file. SHM file DOES still exist in original location.", @"")]:[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully moved SHM file. SHM file DOES still exist in original location.", @"")];
}
else {
statusMessage = replacingShmFile?[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully replaced SHM file. SHM file does NOT still exist in original location.", @"")]:[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully moved SHM file. SHM file does NOT still exist in original location.", @"")];
}
}
else {
statusMessage = replacingShmFile?[NSString stringWithFormat:@"%@ %@ (%@). ",statusMessage,NSLocalizedString(@"Failed to replace SHM file", @""),shmMoveError.localizedDescription]:[NSString stringWithFormat:@"%@ %@ (%@). ",statusMessage,NSLocalizedString(@"Failed to move SHM file", @""),shmMoveError.localizedDescription];
}
}
else {
statusMessage = NSLocalizedString(@"No SHM file to move.", @"");
}
if (handler) {
handler(migrateStoreURL,statusMessage,actuallyMovedFiles,hudIsRunning);
}
});
}
else {
if (handler) {
actuallyMovedFiles = NO;
hudIsRunning = NO;
statusMessage = NSLocalizedString(@"No SQLITE files to move.", @"");
handler(migrateStoreURL,statusMessage,actuallyMovedFiles,hudIsRunning);
}
}
}
编辑:
感谢@matt,问题解决了 - 对于 shm 和 wal 文件,'to' 和 'from' 混淆了。我不敢相信我错过了。所以现在,正如我从在线研究中预期的那样——即使它没有写在文档中——当替换方法成功时,每个文件实际上都被移动了,而不是被复制了。使用我修改和修复的代码,这是我现在得到的消息:
Successfully replaced SQLITE file. SQLITE file does NOT still exist in
original location. Successfully replaced WAL file. WAL file does NOT
still exist in original location. Successfully replaced SHM file. SHM
file does NOT still exist in original location.
我可能错了,但在我看来,您使用概念 "from" 和 "to" 的方式与我使用它们的方式相反。您可能对将文件 从 移动到哪里以及要将它们移动到哪里 到 .
感到困惑
我正在使用 NSFileManager 的 replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:
方法移动 sqlite 文件,以防使用 replacePersistentStoreAtURL:destinationOptions:withPersistentStoreFromURL:sourceOptions:storeType:error:
方法移动失败。该文件包含三个组件文件 - 一个以 .sqlite 结尾,一个以 .sqlite-wal 结尾,一个以 .sqlite-shm 结尾。所有文件都使用 replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:
方法正确地替换了现有的对应文件;但是,实际上只有移动的 .sqlite 文件从其原始位置删除。 .sqlite-wal 和 .sqlite-shm 文件确实会根据需要进行替换,但似乎它们实际上是被复制而不是被移动,因为这两个原始文件在它们恭敬的成功 replacePersistentStoreAtURL:destinationOptions:withPersistentStoreFromURL:sourceOptions:storeType:error:
操作结束时仍然存在.一切都发生在同一卷中,因此似乎没有理由制作副本。谁能帮我弄清楚为什么会这样?
这是代码。稍后记录的状态消息显示为:
Successfully replaced SQLITE file. SQLITE file does NOT still exist in original location. Successfully replaced WAL file. WAL file DOES still exist in original location. Successfully replaced SHM file. SHM file DOES still exist in original location.
- (void)moveSqliteFileFromMigrateStorePathToFinalStorePathWithCompletionHandler:(void(^)(NSURL * migrateStoreURL,NSString * statusMessage,BOOL actuallyMovedFiles,BOOL movingHudIsRunning))handler {
__block NSString *statusMessage = nil;
__block BOOL actuallyMovedFiles = NO;
__block BOOL hudIsRunning = NO;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *applicationDocumentsDirectory = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *migrateStorePath = [applicationDocumentsDirectory stringByAppendingPathComponent:@"MyAppData.sqlite"];
NSURL *migrateStoreURL = [NSURL fileURLWithPath:migrateStorePath];
NSURL *finalStoreURL = [CoreDataController desiredFinalStoreURL];
NSString *finalStorePath = finalStoreURL.path;
NSString *fromWalPath = [migrateStorePath stringByAppendingString:@"-wal"];
NSString *fromShmPath = [migrateStorePath stringByAppendingString:@"-shm"];
BOOL walFileExists = [NSFileManager.defaultManager fileExistsAtPath:fromWalPath];
BOOL shmFileExists = [NSFileManager.defaultManager fileExistsAtPath:fromShmPath];
BOOL sqliteFileExists = [NSFileManager.defaultManager fileExistsAtPath:migrateStorePath];
if (sqliteFileExists || shmFileExists || walFileExists) {
[SVProgressHUD setForegroundColor:CPS_DARK_BLUE_COLOR];
[SVProgressHUD showWithStatus:NSLocalizedString(@"My App is updating. This one-time operation may take several minutes.",@"")];
hudIsRunning = YES;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (sqliteFileExists) {
BOOL finalStorePathFileExists = [NSFileManager.defaultManager fileExistsAtPath:finalStorePath];
NSError * sqliteMoveError = nil;
BOOL successfulSqliteMove = NO;
BOOL replacingSqliteFile = NO;
if (finalStorePathFileExists) {
replacingSqliteFile = YES;
NSURL *migrateStoreURL = [NSURL fileURLWithPath:migrateStorePath];
NSURL *finalStoreURL = [NSURL fileURLWithPath:finalStorePath];
successfulSqliteMove = [[NSFileManager defaultManager] replaceItemAtURL:finalStoreURL withItemAtURL:migrateStoreURL backupItemName:@"sqliteBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&sqliteMoveError];//NSFileManagerItemReplacementUsingNewMetadataOnly
}
else {
successfulSqliteMove = [[NSFileManager defaultManager] moveItemAtPath:migrateStorePath toPath:finalStorePath error:&sqliteMoveError];
}
if (sqliteMoveError) {
DLog(@"The error for the SQLITE move: %@",sqliteMoveError.localizedDescription);
}
if (successfulSqliteMove) {
actuallyMovedFiles = YES;
if([NSFileManager.defaultManager fileExistsAtPath:migrateStorePath]) {
statusMessage = replacingSqliteFile?NSLocalizedString(@"Successfully replaced SQLITE file. SQLITE file DOES still exist in original location.", @""):NSLocalizedString(@"Successfully moved SQLITE file. SQLITE file DOES still exist in original location.", @"");
}
else {
statusMessage = replacingSqliteFile?NSLocalizedString(@"Successfully replaced SQLITE file. SQLITE file does NOT still exist in original location.", @""):NSLocalizedString(@"Successfully moved SQLITE file. SQLITE file does NOT still exist in original location.", @"");
}
}
else {
statusMessage = replacingSqliteFile?[NSString stringWithFormat:@"%@ (%@). ",NSLocalizedString(@"Failed to replace SQLITE file", @""),sqliteMoveError.localizedDescription]:[NSString stringWithFormat:@"%@ (%@). ",NSLocalizedString(@"Failed to move SQLITE file", @""),sqliteMoveError.localizedDescription];
}
}
else {
statusMessage = NSLocalizedString(@"No SQLITE file to move.", @"");
}
if (walFileExists) {
NSString *toWalPath = [finalStorePath stringByAppendingString:@"-wal"];
BOOL toWalFileExists = [NSFileManager.defaultManager fileExistsAtPath:toWalPath];
NSError * walMoveError = nil;
BOOL successfulWalMove = NO;
BOOL replacingWalFile = NO;
if (toWalFileExists) {
replacingWalFile = YES;
NSURL *fromWalURL = [NSURL fileURLWithPath:fromWalPath];
NSURL *toWalURL = [NSURL fileURLWithPath:toWalPath];
//successfulWalMove = [[NSFileManager defaultManager] replaceItemAtURL:fromWalURL withItemAtURL:toWalURL backupItemName:@"walBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&walMoveError];
//THE ABOVE CODE WAS WRONG, WHICH WAS WHAT WAS CAUSING THE ISSUE
successfulWalMove = [[NSFileManager defaultManager] replaceItemAtURL:toWalURL withItemAtURL:fromWalURL backupItemName:@"walBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&walMoveError];
}
else {
successfulWalMove = [[NSFileManager defaultManager] moveItemAtPath:fromWalPath toPath:toWalPath error:&walMoveError];
}
if (walMoveError) {
DLog(@"The error for the WAL move: %@",walMoveError.localizedDescription);
}
if (successfulWalMove) {
actuallyMovedFiles = YES;
if([NSFileManager.defaultManager fileExistsAtPath:fromWalPath]) {
statusMessage = replacingWalFile?[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully replaced WAL file. WAL file DOES still exist in original location.", @"")]:[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully moved WAL file. WAL file DOES still exist in original location.", @"")];
}
else {
statusMessage = replacingWalFile?[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully replaced WAL file. WAL file does NOT still exist in original location.", @"")]:[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully moved WAL file. WAL file does NOT still exist in original location.", @"")];
}
}
else {
statusMessage = replacingWalFile?[NSString stringWithFormat:@"%@ %@ (%@). ",statusMessage,NSLocalizedString(@"Failed to replace WAL file", @""),walMoveError.localizedDescription]:[NSString stringWithFormat:@"%@ %@ (%@). ",statusMessage,NSLocalizedString(@"Failed to move WAL file", @""),walMoveError.localizedDescription];
}
}
else {
statusMessage = NSLocalizedString(@"No WAL file to move.", @"");
}
if (shmFileExists) {
NSString *toShmPath = [finalStorePath stringByAppendingString:@"-shm"];
BOOL toShmFileExists = [NSFileManager.defaultManager fileExistsAtPath:toShmPath];
NSError * shmMoveError = nil;
BOOL successfulShmMove = NO;
BOOL replacingShmFile = NO;
if (toShmFileExists) {
replacingShmFile = YES;
NSURL *fromShmURL = [NSURL fileURLWithPath:fromShmPath];
NSURL *toShmURL = [NSURL fileURLWithPath:toShmPath];
//successfulShmMove = [[NSFileManager defaultManager] replaceItemAtURL:fromShmURL withItemAtURL:toShmURL backupItemName:@"shmBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&shmMoveError];
//THE ABOVE CODE WAS WRONG, WHICH WAS WHAT WAS CAUSING THE ISSUE
successfulShmMove = [[NSFileManager defaultManager] replaceItemAtURL:toShmURL withItemAtURL:fromShmURL backupItemName:@"shmBackup" options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:nil error:&shmMoveError];
}
else {
successfulShmMove = [[NSFileManager defaultManager] moveItemAtPath:fromShmPath toPath:toShmPath error:&shmMoveError];
}
if (shmMoveError) {
DLog(@"The error for the SHM move: %@",shmMoveError.localizedDescription);
}
if (successfulShmMove) {
actuallyMovedFiles = YES;
if([NSFileManager.defaultManager fileExistsAtPath:fromWalPath]) {
statusMessage = replacingShmFile?[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully replaced SHM file. SHM file DOES still exist in original location.", @"")]:[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully moved SHM file. SHM file DOES still exist in original location.", @"")];
}
else {
statusMessage = replacingShmFile?[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully replaced SHM file. SHM file does NOT still exist in original location.", @"")]:[NSString stringWithFormat:@"%@ %@",statusMessage,NSLocalizedString(@"Successfully moved SHM file. SHM file does NOT still exist in original location.", @"")];
}
}
else {
statusMessage = replacingShmFile?[NSString stringWithFormat:@"%@ %@ (%@). ",statusMessage,NSLocalizedString(@"Failed to replace SHM file", @""),shmMoveError.localizedDescription]:[NSString stringWithFormat:@"%@ %@ (%@). ",statusMessage,NSLocalizedString(@"Failed to move SHM file", @""),shmMoveError.localizedDescription];
}
}
else {
statusMessage = NSLocalizedString(@"No SHM file to move.", @"");
}
if (handler) {
handler(migrateStoreURL,statusMessage,actuallyMovedFiles,hudIsRunning);
}
});
}
else {
if (handler) {
actuallyMovedFiles = NO;
hudIsRunning = NO;
statusMessage = NSLocalizedString(@"No SQLITE files to move.", @"");
handler(migrateStoreURL,statusMessage,actuallyMovedFiles,hudIsRunning);
}
}
}
编辑: 感谢@matt,问题解决了 - 对于 shm 和 wal 文件,'to' 和 'from' 混淆了。我不敢相信我错过了。所以现在,正如我从在线研究中预期的那样——即使它没有写在文档中——当替换方法成功时,每个文件实际上都被移动了,而不是被复制了。使用我修改和修复的代码,这是我现在得到的消息:
Successfully replaced SQLITE file. SQLITE file does NOT still exist in original location. Successfully replaced WAL file. WAL file does NOT still exist in original location. Successfully replaced SHM file. SHM file does NOT still exist in original location.
我可能错了,但在我看来,您使用概念 "from" 和 "to" 的方式与我使用它们的方式相反。您可能对将文件 从 移动到哪里以及要将它们移动到哪里 到 .
感到困惑