cout << "equivalence: "
<< equivalent("testdir/foobar.txt",
"testdir/../testdir/foobar.txt")
<< '\n';
}
7. Компиляция и запуск программы дадут следующий результат. Функция current_path()
возвращается к домашнему каталогу на моем ноутбуке, поскольку я запустил приложение оттуда. К нашему относительному пути p
был добавлен префикс, состоящий из данной папки, с помощью функций absolute_path
, system_complete
и canonical
. Мы видим, что функции absolute_path
и system_complete
выдают абсолютно одинаковое описание пути файла в моей системе, потому что это Mac (на Linux будет так же). В компьютере с операционной системой Windows функция system_complete
добавит префикс "C:"
или любого другого диска, в котором расположен рабочий каталог.
$ ./canonical_filepath
current_path : "/Users/tfc"
absolute_path : "/Users/tfc/testdir/foobar.txt"
system_complete : "/Users/tfc/testdir/foobar.txt"
canonical(p) : "/Users/tfc/testdir/foobar.txt"
"testdir/foobar.txt"
canonical testdir : "/Users/tfc/testdir/foobar.txt"
canonical testdir 2 : "/Users/tfc/testdir/foobar.txt"
equivalence: 1
8. Мы не обрабатываем никаких исключений в нашей короткой программе. При удалении файла foobar.txt
из каталога testdir
программа прекращает свою работу из-за исключения. Функция canonical
требует наличия действительного пути файла. Существует также функция weakly_canonical
, которая не предъявляет подобных требований.
$ ./canonial_filepath
current_path : "/Users/tfc"
absolute_path : "/Users/tfc/testdir/foobar.txt"
system_complete : "/Users/tfc/testdir/foobar.txt"
terminate called after throwing an instance of
'std::filesystem::v1:: cxx11::filesystem_error'
what(): filesystem error: cannot canonicalize:
No such file or directory [testdir/foobar.txt] [/Users/tfc]
Как это работает
Цель данного примера заключается в том, чтобы увидеть, как легко создавать новые пути динамически. В основном это связано с наличием в классе path
удобного перегруженного оператора /
. Кроме того, функции файловой системы хорошо работают с абсолютными и относительными путями к файлам, а также с путями, которые содержат косвенные адреса .
и ..
.
Есть довольно много функций, которые возвращают части экземпляра path
, иногда даже преобразуя их. Не будем перечислять все существующие функции, поскольку для знакомства с ними лучше всего обратиться к справочным материалам по C++.
Однако функции-члены класса path
, возможно, стоит рассмотреть поближе. Посмотрим, каким функциям-членам класса path
соответствуют конкретные части пути к файлу. На следующей диаграмме показано, что пути файлов в Windows несколько отличаются от путей файлов в UNIX/Linux (рис. 10.1).
Как видите, функции-члены класса path
возвращаются для root_path
, root_name
и root_directory
пусты. relative_ path
, соответственно, возвращает путь, только если тот уже является относительным.
Составляем список всех файлов в каталоге
Конечно же, каждая операционная система, предлагающая поддержку файловой системы, также поставляется с утилитой, которая просто ls
в Linux, MacOS и других UNIX-подобных операционных системах. В DOS и Windows существует команда dir
. Обе команды составляют список из всех файлов в каталоге и предоставляют дополнительную информацию, такую как размер файла, разрешения и т.д.
Однако переопределение такого инструмента также является хорошим примером, который позволит нам научиться выполнять обходы каталогов и файлов. Давайте просто сделаем это!
Наша собственная утилита ls/dir
будет способна упорядочивать по имени все файлы в каталоге, их флаги разрешения доступа и отображать количество байт, которые они занимают в файловой системе.
Как это делается