Pergunta

Como eu iria renomear um arquivo, mantendo o arquivo no mesmo diretório?

Eu tenho uma string contendo um caminho completo para um arquivo e uma string contendo um novo nome de arquivo (e nenhum caminho), por exemplo:

NSString *old_filepath = @"/Volumes/blah/myfilewithrubbishname.avi";
NSString *new_filename = @"My Correctly Named File.avi";

Eu sei sobre o NSFileManager movePath: toPath: manipulador: método , mas não posso treino como construir caminho do novo arquivo ..

Basicamente, eu estou procurando o equivalente ao seguinte código Python:

>>> import os
>>> old_filepath = "/Volumes/blah/myfilewithrubbishname.avi"
>>> new_filename = "My Correctly Named File.avi"
>>> dirname = os.path.split(old_filepath)[0]
>>> new_filepath = os.path.join(dirname, new_filename)
>>> print new_filepath
/Volumes/blah/My Correctly Named File.avi
>>> os.rename(old_filepath, new_filepath)
Foi útil?

Solução

NSFileManager e NSWorkspace ambos têm métodos de manipulação de arquivo, mas - (BOOL)movePath:(NSString *)source toPath:(NSString *)destination handler:(id)handler de NSFileManager é provavelmente a sua melhor aposta. métodos de manipulação de caminho de uso NSString para obter os nomes de arquivos e pastas direita. Por exemplo,

NSString *newPath = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newFilename];
[[NSFileManager defaultManager] movePath:oldPath toPath:newPath handler:nil];

Ambas as classes são explicados muito bem nos docs, mas deixar um comentário se há alguma coisa que você não entende.

Outras dicas

É importante notar que mover um arquivo para si falhará. Eu tinha um método que substituiu espaços com sublinhados e fez o nome do arquivo em letras minúsculas e renomeado o arquivo para o novo nome. Arquivos com apenas uma palavra em nome falharia a renomeação como o novo nome seria idêntico em um sistema de arquivos de maiúsculas e minúsculas.

A forma como eu resolveu esta era fazer uma renomeação duas etapas, primeiro renomear o arquivo para um nome temporário e, em seguida, renomeá-lo para o nome pretendido.

Alguns pseudocódigo explicando isso:

NSString *source = @"/FILE.txt";
NSString *newName = [[source lastPathComponent] lowercaseString];
NSString *target = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newName];

[[NSFileManager defaultManager] movePath:source toPath:target error:nil]; // <-- FAILS

A solução:

NSString *source = @"/FILE.txt";
NSString *newName = [[source lastPathComponent] lowercaseString];

NSString *temp = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@-temp", newName]];
NSString *target = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newName];

[[NSFileManager defaultManager] movePath:source toPath:temp error:nil];
[[NSFileManager defaultManager] movePath:temp toPath:target error:nil];

Eu só queria tornar isso mais fácil de entender para um novato. Aqui está todo o código:

    NSString *oldPath = @"/Users/brock/Desktop/OriginalFile.png";
NSString *newFilename = @"NewFileName.png";

NSString *newPath = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newFilename];
[[NSFileManager defaultManager] movePath:oldPath toPath:newPath handler:nil];

NSLog( @"File renamed to %@", newFilename );

here's a more recent example for iOS, the NSFileManager method is a little different:

NSString *newFilename = [NSString stringWithFormat:@"%@.m4a", newRecording.title];

NSString *newPath = [[newRecording.localPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newFilename];
[[NSFileManager defaultManager] moveItemAtPath:newRecording.localPath toPath:newPath error:nil];

For the icing on top, a category on NSFileManager:

@implementation NSFileManager (FileManipulations)


- (void)changeFileNamesInDirectory:(NSString *)directory changeBlock:(NSString * (^) (NSString *fileName))block
{
    NSString *inputDirectory = directory;

    NSFileManager *fileManager = [NSFileManager new];

    NSArray *fileNames = [fileManager contentsOfDirectoryAtPath:inputDirectory error:nil];
    for (NSString *fileName in fileNames) {

        NSString *newFileName =  block(fileName);

        NSString *oldPath = [NSString stringWithFormat:@"%@/%@", inputDirectory, oldFileName];
        // move to temp path so case changes can happen
        NSString *tempPath = [NSString stringWithFormat:@"%@-tempName", oldPath];
        NSString *newPath = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newFileName];

        NSError *error = nil;
        [fileManager moveItemAtPath:oldPath toPath:tempPath error:&error];
        if (error) {
            NSLog(@"%@", [error localizedDescription]);
            return;
        }
        [fileManager moveItemAtPath:tempPath toPath:newPath error:&error];
        if (error) {
            NSLog(@"%@", [error localizedDescription]);
        }
    }
}


@end
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top