Переименовать файл в Cocoa?
Как мне переименовать файл, сохранив файл в том же каталоге?
У меня есть строка, содержащая полный путь к файлу, и строка, содержащая новое имя файла (и никакой путь), например:
NSString *old_filepath = @"/Volumes/blah/myfilewithrubbishname.avi";
NSString *new_filename = @"My Correctly Named File.avi";
Я знаю о NSFileManager movePath:toPath:handler:, но я не могу тренироваться, как построить новый путь к файлу.
В основном я ищу эквивалент следующего кода 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)
Ответы
Ответ 1
NSFileManager и NSWorkspace имеют методы манипуляции файлами, но NSFileManager - (BOOL)movePath:(NSString *)source toPath:(NSString *)destination handler:(id)handler
, вероятно, лучший выбор. Используйте методы управления трассировкой NSString, чтобы правильно получить имена файлов и папок. Например,
NSString *newPath = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newFilename];
[[NSFileManager defaultManager] movePath:oldPath toPath:newPath handler:nil];
Оба класса хорошо объясняются в документах, но оставляйте комментарий, если что-то не понимаете.
Ответ 2
Стоит отметить, что переместить файл самому себе не удастся. У меня был метод, который заменил пробелы символами подчеркивания и сделал имя файла строчным и переименовал файл в новое имя. Файлы с одним словом в имени не смогут переименовать, поскольку новое имя будет идентичным в файловой системе без регистра.
Как я решил это сделать, нужно сделать двухэтапное переименование, сначала переименовав файл во временное имя, а затем переименовав его в назначенное имя.
Некоторые псевдокоды, объясняющие это:
NSString *source = @"/FILE.txt";
NSString *newName = [[source lastPathComponent] lowercaseString];
NSString *target = [[oldPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newName];
[[NSFileManager defaultManager] movePath:source toPath:target error:nil]; // <-- FAILS
Решение:
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];
Ответ 3
Я просто хотел, чтобы это стало понятным для новичков. Здесь весь код:
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 );
Ответ 4
здесь более свежий пример для iOS, метод NSFileManager немного отличается:
NSString *newFilename = [NSString stringWithFormat:@"%@.m4a", newRecording.title];
NSString *newPath = [[newRecording.localPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:newFilename];
[[NSFileManager defaultManager] moveItemAtPath:newRecording.localPath toPath:newPath error:nil];
Ответ 5
Для обледенения сверху, категория в 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