Функция create_directory создает каталог, имя которого вы задаете в аргументе path. Если этот каталог уже существует, выбрасывается исключение filesystem_error (которое является производным от стандартного класса исключения). Пояснения по классу path и функции complete (оба они входят в библиотеку Boost Filesystem) приводятся в обсуждении рецепта 10.7. См. рецепт 10.11, где показан пример удаления каталога и всех содержащихся в нем файлов. С другой стороны, если переносимость вас не волнует, используйте программный интерфейс файловой системы вашей ОС, который, вероятно, обладает большей гибкостью.

Смотри также

Рецепт 10.12.

<p>10.11. Удаление каталога</p>Проблема

Требуется удалить каталог, причем эта операция должна быть переносимой, т.е. в ней не должен использоваться специфичный для конкретной ОС программный интерфейс.

Решение

На большинстве платформ вы сможете воспользоваться системным вызовом rmdir, который входит в состав большинства компиляторов и содержится в заголовочных файлах C-функций. Стандартными средствами C++ нельзя обеспечить переносимый способ удаления каталога. Вызов rmdir имеет разный вид в различных ОС, но тем не менее вы можете его использовать для удаления каталога. См. Пример 10.17, в котором приводится короткая программа по удалению каталога.

Пример 10.17. Удаление каталога

#include

#include

using namespace std;

int main(int argc, char** argv) {

 if (argc < 2) {

  cerr << "Usage: " << argv[0] << " [dir name]" << endl;

  return(EXIT_FAILURE);

 }

 if (rmdir(argv[1]) == -1) { // Удалить каталог

  cerr << "Error: " << strerror(errno) << endl;

  return(EXIT_FAILURE);

 }

}

Обсуждение

Сигнатура rmdir совпадает в большинстве ОС, однако объявляется эта функция в разных заголовочных файлах. В Windows она объявляется в , а в Unix — в . Она принимает один параметр (имя каталога) и возвращает -1, если возникла ошибка, устанавливая в errno соответствующий номер ошибки. Вы можете получить зависящую от реализации текстовую строку ошибки, вызывая strerror или perror.

Если целевой каталог не пустой, rmdir завершится с ошибкой. Для просмотра списка содержимого каталога, перечисления его элементов для их удаления см. рецепт 10.12.

Если вам требуется обеспечить переносимость, не следует самому писать операторы #ifdef, заключая в них специфичные для конкретной ОС функции, — лучше воспользоваться библиотекой Boost Filesystem. В библиотеке Boost Filesystem используется концепция пути для ссылки на файл или каталог, а пути можно удалять с помощью одной функции — remove.

Функция removeRecurse из примера 10.18 рекурсивно удаляет каталог и все его содержимое. Наиболее важной ее частью является функция remove (которая на самом деле является функцией boost::filesystem::remove, а не стандартной библиотечной функцией). Она принимает путь path в качестве аргумента и удаляет его, если это файл или пустой каталог, но она не удаляет каталог, если он содержит файлы.

Пример 10.18. Удаление каталога средствами Boost

#include

#include

#include

#include

#include

using namespace std;

using namespace boost::filesystem;

void removeRecurse(const path& p) {

 // Сначала удалить содержимое каталога

 directory_iterator end;

 for (directory_iterator it(p); it != end; ++it) {

  if (is_directory(*it)) {

   removeRecurse(*it);

  } else {

   remove(*it);

  }

 }

 // Затем удалить сам каталог

 remove(p);

}

int main(int argc, char** argv) {

 if (argc != 2) {

  cerr << "Usage: " << argv[0] << " [dir name]\n";

  return(EXIT_FAILURE);

 }

 path thePath = system_complete(path(argv[1], native));

 if (!exists(thePath)) {

  cerr << "Error: the directory " << thePath.string()

   << " does not exist.\n";

  return(EXIT_FAILURE);

 }

 try {

  removeRecurse(thePath);

 } catch (exception& e) {

  cerr << e.what() << endl;

  return(EXIT_FAILURE);

 }

 return(EXIT_SUCCESS);

}

Перейти на страницу:

Похожие книги