Возможно, вам потребуется время, чтобы это переварить. В нашей функции main цепочка вызовов auto result (pconcat(...));
result()
, мы async
и .get()
, которые выполнялись в правильном порядке, чтобы не заблокировать друг друга. Фактически вызовы get()
не происходят до вызовов async
.В конечном счете мы наконец можем вызвать функцию .get()
future
, которое вернула функция result()
, и получить финальную строку. Глава 10
Файловая система
В этой главе:
□ реализация нормализатора пути к файлу;
□ получение канонических путей к файлам из относительных путей;
□ составление списка всех файлов в каталоге;
□ реализация средства поиска текста в стиле grep
□ реализация автоматического средства для переименования файлов;
□ реализация счетчика использования диска;
□ вычисление статистики о типах файлов;
□ реализация средства, которое уменьшает размер папки путем замены дубликатов символьными ссылками.
Введение
Работа с путями файлов в файловой системе всегда утомительна, если у нас нет специальной библиотеки, поскольку при решении данной задачи необходимо учитывать множество условий.
Одни пути файлов являются
.
(текущий каталог) и ..
(родительский каталог). В то же время в различных операционных системах для разделения каталогов используется слеш /
(Linux, MacOS и различные системы UNIX) или обратный слеш \
(Windows). И конечно же, существуют разные типы файлов.Поскольку каждая вторая программа, связанная с работой в файловой системе, нуждается в таком функционале, было бы здорово иметь новую библиотеку файловой системы в C++17 STL. Самое лучшее в данной ситуации то, что принцип работы одинаков для разных операционных систем, поэтому не требуется писать разные фрагменты кода для версий программ, поддерживающих разные операционные системы.
В этой главе мы сначала рассмотрим принцип работы класса path
directory_iterator
и recursive_directory_iterator
при работе с файлами. В конце главы задействуем в примерах маленькие и простые инструменты, которые выполняют реальные задачи, связанные с файловой системой. С этого момента можно будет легко создавать более сложные инструменты. Реализуем нормализатор пути файла
Мы начинаем эту главу с очень простого примера, иллюстрирующего работу класса std::filesystem::path
Результатом данного примера является небольшое приложение, которое принимает любой путь к файлу и возвращает его в нормализованной форме. Нормализованный путь к файлу — абсолютный путь к файлу, не содержащий косвенных адресов .
..
.При реализации примера мы также увидим, на какие детали следует обратить внимание во время работы с этой базовой частью библиотеки, связанной с файловой системой.
Как это делается
В этом примере мы реализуем программу, которая всего лишь принимает путь к файлу как аргумент командной строки, а затем отображает его в нормализованной форме.
1. Файл с кодом начинается с директив include
std
и filesystem
:#include
#include
using namespace std;
using namespace filesystem;
2. В функции main
filesystem::path
:int main(int argc, char *argv[])
{
if (argc != 2) {
cout << "Usage: " << argv[0] << "
return 1;
}
const path dir {argv[1]};
3. Поскольку можно создавать объекты класса path
filesystem::exists
. Если данного пути к файлу не существует, то просто снова отображаем сообщение об ошибке: if (!exists(dir)) {
cout << "Path " << dir << " does not exist.\n";
return 1;
}