Pregunta

¿Cómo puedo cambiar el nombre de un archivo, manteniendo el archivo en el mismo directorio?

Tengo una cadena que contiene una ruta de acceso completa a un archivo y una cadena que contiene un nuevo nombre de archivo (y no hay camino), por ejemplo:

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

Yo sé de movePath: toPath: manejador: método , pero no puedo entrenar la forma de construir el camino del nuevo archivo ..

Básicamente estoy buscando el equivalente al siguiente 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)
¿Fue útil?

Solución

NSFileManager y NSWorkspace ambos tienen métodos de manipulación de archivos, pero - (BOOL)movePath:(NSString *)source toPath:(NSString *)destination handler:(id)handler de NSFileManager es probablemente su mejor apuesta. Utilizar métodos de manipulación de rutas de NSString para obtener los nombres de archivos y carpetas derecha. Por ejemplo,

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

Ambas clases se explican bastante bien en la documentación, pero dejan un comentario si hay algo que no entiende.

Otros consejos

Vale la pena señalar que mover un archivo a la misma se producirá un error. Tenía un método que sustituye espacios con guiones e hizo el nombre del archivo en minúsculas y cambió el nombre del archivo con el nuevo nombre. Los archivos con una sola palabra en el nombre fracasarían el cambio de nombre como el nuevo nombre sería idéntica en un sistema de archivos entre mayúsculas y minúsculas.

La forma en que esto fue resuelto a hacer un cambio de nombre de dos pasos, primero cambiar el nombre del archivo a un nombre temporal y luego cambiar el nombre a la denominación prevista.

Algunos pseudocódigo explicando esto:

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

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

La solución:

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];

Sólo quería hacer esto más fácil de entender para un novato. Aquí está todo el 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 );

aquí es un ejemplo más reciente de iOS, el método NSFileManager es un poco diferente:

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

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

Para la formación de hielo en la parte superior, una categoría en 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top