#swift #macos #command-line
#swift #macos #командная строка
Вопрос:
Итак, я создаю инструмент командной строки в Swift, который принимает путь к файлу в качестве аргумента. Я проверяю, существует ли путь к файлу, иначе я выдаю ошибку. Когда я использую абсолютный путь, все работает так, как должно. Когда я использую относительный путь, это не так.
код:
let pwdURL = URL(string: "file://" FileManager.default.currentDirectoryPath)
print("pwdURL: ", pwdURL ?? "no pwdURL")
let pathURL = URL(string: path, relativeTo: pwdURL)
print("pathURL: ", pathURL ?? "no pathURL")
do {
let _ = try pathURL?.checkResourceIsReachable()
}
catch {
print(error)
throw ValidationError("(path) Is not a valid path.")
}
команда:
Из /Users/myUser/Projects/myProject
папки, в терминале.
swift run myProject ../../Downloads/myFile.pdf
вывод:
pwdURL: file:///Users/myUser/Projects/myProject
pathURL: ../../Downloads/myFile.pdf -- file:///Users/myUser/Projects/myProject
Error Domain=NSCocoaErrorDomain Code=260 "The file “myFile.pdf” couldn’t be opened because there is no such file." UserInfo={NSURL=../../Downloads/myFile.pdf -- file:///Users/myUser/Projects/myProject, NSFilePath=/Users/Downloads/myFile.pdf, NSUnderlyingError=0x7fad39d0c280 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
Error: ../../Downloads/myFile.pdf Is not a valid path.
Я ожидал, что он будет искать /Users/myUser/Downloads/myFile.pdf
, потому что это допустимый путь, с которого я ввожу команду в терминале. Кроме того, когда я смотрю на вывод из pathURL ( ../../Downloads/myFile.pdf -- file:///Users/myUser/Projects/myProject
), похоже, что это приведет к правильному пути?
Но, как вы можете видеть, возникает ошибка, потому что он ищет /Users/Downloads/myFile.pdf
, которого не существует.
Ответ №1:
Требуется, чтобы relativeTo
параметр заканчивался на a /
, чтобы это работало так, как вы ожидаете. Из документов NSURL (курсив добавлен):
Этот метод позволяет создать URL-адрес относительно базового пути или URL-адреса. Например, если у вас есть URL-адрес папки на диске и имя файла в этой папке, вы можете создать URL-адрес для файла, указав URL-адрес папки в качестве базового пути (с завершающей косой чертой) и имя файла в качестве строковой части.
Итак, что вам нужно здесь:
let pwdURL = URL(string: "file://" FileManager.default.currentDirectoryPath "/")
Но я бы на самом деле сделал это так:
let pwdURL = URL(fileURLWithPath: FileManager.default.currentDirectoryPath)
или:
let pwdURL = Process().currentDirectoryURL
Обычно мне проще это сделать, используя appendingPathComponent
, что немного проще в правильном использовании:
let pathURL = pwdURL.appendingPathComponenent(path)
Разница в том, что это оставит ../..
путь, а не разрешит их, так что это зависит от того, что вы хотите.
Комментарии:
1. Другой вариант — создать базовый URL с
URL(fileURLWithPath: ..., isDirectory: true)
2. хех; Я просто дважды проверял, как это сделать правильно.