10.11. Удаление каталога
10.11. Удаление каталога
Проблема
Требуется удалить каталог, причем эта операция должна быть переносимой, т.е. в ней не должен использоваться специфичный для конкретной ОС программный интерфейс.
Решение
На большинстве платформ вы сможете воспользоваться системным вызовом rmdir, который входит в состав большинства компиляторов и содержится в заголовочных файлах C-функций. Стандартными средствами C++ нельзя обеспечить переносимый способ удаления каталога. Вызов rmdir имеет разный вид в различных ОС, но тем не менее вы можете его использовать для удаления каталога. См. Пример 10.17, в котором приводится короткая программа по удалению каталога.
Пример 10.17. Удаление каталога
#include <iostream>
#include <direct.h>
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 она объявляется в <direct.h>, а в Unix — в <unistd.h>. Она принимает один параметр (имя каталога) и возвращает -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 <iostream>
#include <string>
#include <cstdlib>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>
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] ";
return(EXIT_FAILURE);
}
path thePath = system_complete(path(argv[1], native));
if (!exists(thePath)) {
cerr << "Error: the directory " << thePath.string()
<< " does not exist. ";
return(EXIT_FAILURE);
}
try {
removeRecurse(thePath);
} catch (exception& e) {
cerr << e.what() << endl;
return(EXIT_FAILURE);
}
return(EXIT_SUCCESS);
}
Программный код, обеспечивающий просмотр содержимого каталога, требует некоторых пояснений, и это является темой рецепта 10.12.
Библиотека Boost Filesystem достаточно удобна, однако следует помнить, что формально она не является стандартом, и поэтому нет гарантии, что она будет работать в любой среде. Если вы посмотрите на исходный код библиотеки Boost Filesystem, вы увидите, что фактически она компилирует системные вызовы, специфичные для целевой платформы. Если вас не волнует переносимость, используйте программный интерфейс файловой системы вашей ОС, который, вполне вероятно, обладает большей гибкостью.
Смотри также
Рецепт 10.12.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
14.4.6. Удаление вершины дерева и удаление дерева: tdelete() и tdestroy()
14.4.6. Удаление вершины дерева и удаление дерева: tdelete() и tdestroy() Наконец, вы можете удалить элементы из дерева и, на системах GLIBC, удалить само дерево целиком:void *tdelete(const void *key, void **rootp,int (*compare)(const void*, const void*));/* Расширение GLIBC, в POSIX нет: */void tdestroy(void *root, void (*free_node)(void *nodep));Аргументы
14.1.3. Смена текущего каталога
14.1.3. Смена текущего каталога Предусмотрено два системных вызова, меняющих текущий каталог процесса: chdir() и fchdir().#include <unistd.h>int chdir(const char * pathname);int fchdir(int fd);Первый системный вызов получает имя каталога в качестве единственного аргумента; второй принимает файловый
14.2. Смена корневого каталога
14.2. Смена корневого каталога Хотя в системе имеется один корневой каталог, значение / может меняться для каждого процесса в системе. Это обычно делается для предотвращения доступа к файловой системе со стороны сомнительных процессов (например, демоны ftp, обрабатывающие
14.4. Чтение содержимого каталога
14.4. Чтение содержимого каталога Обычно программам требуется получать список файлов, содержащихся в каталоге. Linux предоставляет ряд функций, позволяющих обрабатывать каталог как абстрактный объект, что дает возможность избежать зависимости программ от точного формата
14.8. Уведомление о смене каталога
14.8. Уведомление о смене каталога Иногда приложения желают получать уведомления об изменении оглавления каталога. Например, диспетчеры файлов могут выводить оглавление каталога в окне и обновлять это окно каждый раз при изменении каталога другими программами. В то время
16.19.1 Модель каталога
16.19.1 Модель каталога Информационная база каталога (Directory Information Base) распределена среди группы баз данных, управляемых агентами обслуживания каталогов (Directory Service Agent — DSA). Пользователи обращаются к каталогам через пользовательский агент каталога (Directory User Agent — DUA). DUA
1.7.3. Структура каталога
1.7.3. Структура каталога На сегодня в каталоге Яндекса 15 разделов первого уровня (рис. 1.16). Помимо привычных, встречающихся и в иных каталогах разделов — Отдых, Бизнес, Культура и иных, в этом каталоге есть уникальный раздел. Он предназначен для детей и называется "Интернет
Меню каталога
Меню каталога Меню каталога обязательно должно быть вертикальным! В ходе многочисленных тестов выяснилось, что горизонтальное меню менее эффективно и вызывает у людей больше трудностей. Кроме того, практика показывает, что подавляющее большинство людей интуитивно ищут
Страница каталога
Страница каталога На самой странице каталога пользователь обязательно должен видеть товары – конкретные предложения о покупке. Чаще всего владельцы интернет-магазинов спрашивают, сколько товаров нужно показывать на странице каталога.Однозначного ответа нет. Это
10.1.30. Обход каталога
10.1.30. Обход каталога Метод класса foreach — это итератор, который последовательно передает в блок каждый элемент каталога. Точно так же ведет себя метод экземпляра each.Dir.foreach("/tmp") { |entry| puts entry }dir = Dir.new("/tmp")dir.each { |entry| puts entry }Оба фрагмента печатают одно и то же (имена всех файлов и
10.10. Создание каталога
10.10. Создание каталога ПроблемаТребуется создать каталог, причем эта операция должна быть переносимой, т.е. в ней не должен использоваться специфичный для конкретной ОС программный интерфейс.РешениеНа большинстве платформ вы сможете использовать системный вызов mkdir,
Удаление ключа из вашего каталога ключей.
Удаление ключа из вашего каталога ключей. Для удаления ключа из вашего каталога открытых ключей наберите:pgp –kr userid [keyring]PGP будет искать заданный идентификатор пользователя в вашем каталоге открытых ключей и, при нахождении оного, удалит его. Не забудьте, что любого