Пост

Играемся с std:filesystem [C++17]

В C++17 добавлено новое пространство имен std::filesystem. На мой взгляд он предоставляет удобный интерфейс для работы с файловой системой. Тогда как раньше приходилось складывать строки и вызывать си функции для манипуляций атрибутами файлов.

Как компилить?

  • Установить С++17
  • Указать линковщику флаг -lstdc++fs
1
 g++-7 main.cpp -o main -lstdc++fs

Начинаем эксперементировать

Для удобства я переопределил namespace. (все так делают)

1
namespace fs = std::experimental::filesystem;

Первый пример

Сущность fs::path представляет путь к объектам файловой системы. И некоторые его методы.

1
2
3
4
5
6
7
fs::path p {"./path/file.txt"};
std::cout << "parent_path: " << p.parent_path() << std::endl;
std::cout << "extension: " << p.extension() << std::endl;
std::cout << "filename: " << p.filename() << std::endl;
std::cout << "root_name: " << p.root_name() << std::endl;
std::cout << "has_relative_path: " << p.has_relative_path() << std::endl;
std::cout << "has_root_directory: " << p.has_root_directory() << std::endl;

На выходе получим информацию о заданном пути и файле.

1
2
3
4
5
6
parent_path: "./path"
extension: ".txt"
filename: "file.txt"
root_name: ""
has_relative_path: 1
has_root_directory: 0

Кроссплатформенный разделитель

Раньше для определения разделителя в зависимости от операционной системы приходилось выкручиватся применением условных директив. Сейчас для этой цели можно применить следующий метод.

1
std::cout << "preferred_separator: " << fs::path::preferred_separator << std::endl;

Output:

1
preferred_separator: /

Применение перегруженного знака деления для получения полного пути.

Как по мне такой способ удобен тем, что при чтении, код явно говорит нам, что мы работаем с файловой системой уже в привычном нам виде.

1
2
3
4
5
6
7
fs::path root {"/"};
fs::path httpd { "etc/httpd/" };
fs::path sites {"sites-enabled"};
fs::path conf {"site.conf"};

fs::path path_to_site_conf = root / httpd / sites / conf;
std::cout << "path_to_site_conf: " << path_to_site_conf << std::endl;

Output:

1
path_to_site_conf: "/etc/httpd/sites-enabled/site.conf"

Рекурсивное создание и удаление каталогов

1
2
3
4
5
fs::create_directories("banana/cocosa/mango");
fs::create_directories("banana/apple/kiwi");
system("ls -a banana/*");
fs::remove_all("banana");
system("ls -a banana/*");

Output:

1
2
3
4
5
6
banana/apple:
.  ..  kiwi

banana/cocosa:
.  ..  mango
ls: cannot access 'banana/*': No such file or directory
Авторский пост защищен лицензией CC BY 4.0 .