在某些情况下,replaceItemAtURL:方法无法删除原始移动的文件

时间:2018-09-19 18:56:37

标签: ios nsfilemanager

在使用replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:方法无法移动sqlite文件的情况下,我正在使用NSFileManager的replacePersistentStoreAtURL:destinationOptions:withPersistentStoreFromURL:sourceOptions:storeType:error:方法来移动sqlite文件。该文件包含三个组件文件-一个以.sqlite结尾的文件,一个以.sqlite-wal结尾的文件,以及一个以.sqlite-shm结尾的文件。所有文件都可以使用replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:方法正确替换现有文件;但是,实际上仅从其原始位置删除了移动的.sqlite文件。 .sqlite-wal和.sqlite-shm文件确实可以按需替换,但似乎实际上是复制而不是移动它们,因为这两个原始文件在其成功完成replacePersistentStoreAtURL:destinationOptions:withPersistentStoreFromURL:sourceOptions:storeType:error:操作之后仍在原位。一切都在同一卷中进行,因此似乎没有理由制作副本。有人可以帮我弄清楚为什么会这样吗?

这是代码。状态消息在稍后记录时显示为:

  

成功替换了SQLITE文件。 SQLITE文件仍不存在   原始位置。成功替换WAL文件。 WAL文件仍然存在   存在于原始位置。成功替换了SHM文件。 SHM文件   仍然存在于原始位置。

- (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”混合在一起了。我简直不敢错过。因此,现在,正如我在网上进行的研究所期望的那样-即使它没有写在文档中-当replace方法成功时,每个文件实际上都被移动而不是复制。使用我的修订和固定代码,这是我现在收到的消息:

  

成功替换了SQLITE文件。 SQLITE文件仍不存在   原始位置。成功替换WAL文件。 WAL文件不   仍然存在于原始位置。成功替换了SHM文件。 SHM   文件在原始位置仍然不存在。

1 个答案:

答案 0 :(得分:1)

我可能是错的,但乍一看,您似乎在使用“从”和“到”两个概念,这与我使用它们的方式相反。您可能对将文件移至何处以及要将文件移至的位置感到困惑。