Каков современный способ Swift изменить имя файла в каталоге документов, когда вам нужно заменить существующий файл с целевым именем, если он существует?
(По этой причине я не использую moveItem... а использую replaceItem
Есть много вопросов по этому поводу, возникающих много лет назад, например, здесь, но я не могу найти ни одного, который бы работал на меня.
Например:
let oldpicname = "22_contactpic.png"
let newpicname = "9213_contactpic.png"
do {
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let documentDirectory = URL(fileURLWithPath: path)
let originPath = documentDirectory.appendingPathComponent(oldpicname)
let destinationPath = documentDirectory.appendingPathComponent(newpicname)
try
print("try to replace file")
FileManager.default.replaceItemAt(originPath, withItemAt: destinationPath)
} catch {
print("FIRST TRY FAILED TO RENAME FILE")
print(error)
}
Компилируется и не выдает ошибку, но когда я потом проверяю файл, он не существует.
Мэтт в приведенной выше ссылке предлагает следующее:
var rv = URLResourceValues()
rv.name = newname
try? url.setResourceValues(rv)
Это дает ряд ошибок, которые я не могу устранить, в том числе невозможно использовать мутирующий член для неизменяемого значения.
Примечание. Я могу сделать это в Objective-C с помощью следующего кода:
- (void)renameWithReplaceFileWithName:(NSString *)beforeName toName:(NSString *)afterName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePathBefore = [documentsDirectory stringByAppendingPathComponent:beforeName];
NSString *filePathAfter = [documentsDirectory stringByAppendingPathComponent:afterName];
NSLog(@"filepath after is%@. This will be the new name of this file",filePathAfter);
NSFileManager *manager = [NSFileManager defaultManager];
if ([manager fileExistsAtPath:filePathBefore]) {
NSError *error = nil;
NSURL *previousItemUrl = [NSURL fileURLWithPath: filePathBefore];/
NSURL *currentItemUrl = [NSURL fileURLWithPath:filePathAfter];
[[NSFileManager defaultManager] replaceItemAtURL:previousItemUrl withItemAtURL:currentItemUrl backupItemName:nil options:0 resultingItemURL:nil error:&error];
if (error) {
// handle error
}
}
}
Спасибо за любые предложения.
У вас есть все, что нужно, чтобы изменить имя файла. Используйте try FileManager.default.replaceItemAt(destinationPath, withItemAt: originPath). Обратите внимание: не ставьте try перед print("try to replace file"), только перед FileManager.default.....
вам нужно объявить свой URL как var
у меня работает с let





У меня это работает, чтобы изменить имя файла, используя исходный код с небольшими изменениями.
func replace() {
let oldpicname = "22_contactpic.png"
let newpicname = "9213_contactpic.png"
do {
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let documentDirectory = URL(fileURLWithPath: path)
let originPath = documentDirectory.appendingPathComponent(oldpicname)
let destinationPath = documentDirectory.appendingPathComponent(newpicname)
// -- here, note the change
let results = try FileManager.default.replaceItemAt(destinationPath, withItemAt: originPath)
print("----> results: \(results)")
} catch {
print("FIRST TRY FAILED TO RENAME FILE")
print(error)
}
}
Альтернативно, без NSSearchPathForDirectoriesInDomains проверка существования файла и использование moveItem(...):
func renameFile(from oldName: String, to newName: String) {
let docDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let oldFilePath = docDir.appendingPathComponent(oldName)
let newFilePath = docDir.appendingPathComponent(newName)
// check that the file exist first
if FileManager.default.fileExists(atPath: oldFilePath.path) {
do {
try FileManager.default.moveItem(at: oldFilePath, to: newFilePath)
print("---> File renamed \n from: \(oldFilePath) \n to: \(newFilePath)")
} catch {
print("---> Error renaming file: \(error)")
}
} else {
print("----> \(oldFilePath) does not exist")
}
}
Уверяю вас, что мой подход к изменению имени файла работает. Однако я вовсе не уверен, что вы этого хотите; вы вроде бы говорите, что хотите заменить сам файл, а это другое дело.