ReplaceItemAtURL: метод не может удалить оригинальные перемещенные файлы в некоторых случаях - PullRequest
0 голосов
/ 19 сентября 2018

Я использую метод 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:.Все происходит в одном и том же объеме, поэтому, похоже, нет причин, по которым можно было бы делать копии.Может кто-нибудь помочь мне понять, почему это может происходить?

Вот код.Сообщение о состоянии, когда оно регистрируется позже, гласит:

Успешно заменен файл 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' были смешанывверх.Я не могу поверить, что я пропустил это.Итак, теперь, как я и ожидал, из онлайн-исследований - даже если это не написано в документации - каждый файл фактически перемещается, а не копируется, когда метод замены успешен.С моим исправленным и исправленным кодом я получаю следующее сообщение:

Успешно заменен файл SQLITE.Файл SQLITE НЕ все еще существует в исходном местоположении.Успешно заменен файл WAL.WAL-файл НЕ все еще существует в исходном местоположении.Успешно заменен файл SHM.Файл SHM по-прежнему не существует в исходном местоположении.

1 Ответ

0 голосов
/ 20 сентября 2018

Я могу ошибаться, но на первый взгляд мне кажется, что вы используете понятия «от» и «в» в противоположность тому, как я их использовал.Вы можете быть озадачены тем, куда вы перемещаете файлы из и куда вы хотите переместить их в .

...