4. Итак, на данном этапе мы вполне уверены: пользователь предоставил
filesystem::canonical
возвращает другой объект класса path
. Мы можем вывести на экран его напрямую, но перегруженный оператор <<
класса path
берет в кавычки пути к файлу. Чтобы этого избежать, можем отобразить путь к файлу с помощью методов .c_str()
или .string()
: cout << canonical(dir).c_str() << '\n';
}
5. Скомпилируем программу и поработаем с ней. Когда мы запустим ее в домашнем каталоге и передадим относительный путь к файлу "src"
$ ./normalizer src
/Users/tfc/src
6. Когда мы снова запускаем программу в домашнем каталоге, но даем ей запутанное относительное описание пути к файлу, в котором сначала прописывается вход в папку Desktop
, потом прописывается выход из нее с помощью косвенного адреса..
, затем входим в папку Documents и выходим из нее, чтобы в конечном итоге попасть в каталог src
, программа отображает $ ./normalizer Desktop/../Documents/../src
/Users/tfc/src
Как это работает
Этот начальный пример работы с std::filesystem
std::filesystem::path
имеет самое первостепенное значение в тех ситуациях, когда мы используем библиотеку, связанную с файловой системой, поскольку с ним связано большинство функций и классов.Функция filesystem::exists
path
, которые не относятся к реальному объекту файловой системы. Функция exists
всего лишь принимает экземпляр класса path
и возвращает значение true в том случае, если он действительно существует. Эта функция способна сама определить, какой путь мы ей передали (абсолютный или относительный), что делает ее очень комфортной в применении.Наконец, мы использовали функцию filesystem::canonical
path canonical(const path& p, const path& base = current_path());
Функция canonical
base
добавляется к пути файла p
в том случае, если p
является относительным. После этого функция canonical
пытается убрать все косвенные адреса .
и ..
.Для вывода результата на экран мы использовали метод .c_str()
<<
для выходных потоков берет пути к файлам в кавычки, а это не всегда желательно.Дополнительная информация
Функция canonical
fileystem_error
, если путь, который мы хотим привести к каноническому виду, не существует. Для предотвращения этого мы проверили наш путь к файлу с помощью функции exists
. Но было ли достаточно данной проверки, чтобы необработанные исключения не генерировались? Нет.Обе функции, как exists
canonical
, способны генерировать исключения типа bad_alloc
. Если бы эти исключения сгенерировались, кто-то мог бы утверждать, что программа все равно обречена. Более важная, а также гораздо более вероятная проблема возникает, когда где-то между проверкой существования файла и процессом приведения его к каноническому виду некто переименовывает или удаляет основной файл! В этом случае функция canonical
сгенерирует сообщение об ошибке filesystem_error
, хотя мы ранее уже убедились в том, что файл существует.Большая часть функций файловой системы имеет еще одну перегруженную версию, которая принимает те же аргументы, а также ссылку на std::error_code
path canonical(const path& p, const path& base = current_path());
path canonical(const path& p, error_code& ec);
path canonical(const std::filesystem::path& p,
const std::filesystem::path& base,
std::error_code& ec);