Смотри также

Рецепт 10.12.

10.12. Чтение содержимого каталога

Проблема

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

Решение

Для получения переносимого решения воспользуйтесь классами и функциями библиотеки Boost Filesystem. Она содержит ряд удобных функций по работе с файлами, обеспечивая переносимое представление путей, итераторы каталога и различные функции по переименованию, удалению и копированию файлов и т.п. Пример 10.19 показывает, как можно использовать некоторые из этих средств.

Пример 10.19. Чтение каталога

#include <iostream>

#include <boost/filesystem/operations.hpp>

#include <boost/filesystem/fstream.hpp>

using namespace boost::filesystem;

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

 if (argc < 2) {

  std::cerr << 'Usage: ' << argv[0] << ' [dir name] ';

  return(EXIT_FAILURE);

 }

 path fullPath = // Создать полный, абсолютный путь

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

 if (!exists(fullPath)) {

  std::cerr << 'Error: the directory ' << fullPath.string()

   << ' does not exist. ';

  return(EXIT_FAILURE);

 }

 if (!is_directory(fullPath)) {

  std::cout << fullPath.string() << ' is not a directory! ';

  return(EXIT_SUCCESS);

 }

 directory_iterator end;

 for (directory_iterator it(fullPath);

  it != end; ++it) {        // Просматривать в цикле каждый

                           // элемент каталога почти

  std::cout << it->leaf(); // так же, как это делалось бы для

  if (is_directory(*it))   // STL-контейнера

   std::cout << ' (dir)';

  std::cout << ' ';

 }

 return(EXIT_SUCCESS);

}

Обсуждение

Как и при создании и удалении каталогов (см. рецепты 10.10 и 10.11), не существует стандартного, переносимого способа чтения содержимого каталога. Чтобы облегчить жизнь в C++, библиотека Filesystem проекта Boost содержит ряд переносимых функций по работе с файлами и каталогами. Она также содержит много других функций; дополнительную информацию вы найдете при описании других рецептов этой главы или на веб-странице библиотеки Boost Filesystem сайта www.boost.com.

В примере 10.19 приводится простая программа просмотра каталога (наподобие команды ls в Unix или dir в MS-DOS). Сначала она следующим образом формирует абсолютный путь на основе аргументов, переданных программе.

path fullPath = complete(path(argv[1], native));

Тип данных переменной, содержащей путь, называется, естественно, path (путь). С этим типом данных работает файловая система, и он легко преобразуется в строку путем вызова path::string. После формирования пути программа проверяет его существование (с помощью функции exists), затем с помощью другой функции, is_directory, проверяет, задает ли данный путь каталог. Если ответ положителен, то все хорошо и можно перейти к реальной работе по просмотру содержимого каталога.

Файловая система имеет класс с именем directory_iterator, который использует стандартную семантику итераторов, подобную применяемой для стандартных контейнеров, чтобы можно было использовать итераторы как указатели на элементы каталога. Однако в отличие от стандартных контейнеров здесь нет функции-члена end, представляющей элемент, следующий за последним элементом (т.е. vector<T>::end). Вместо этого, если вы создаете итератор каталога directory_iterator при помощи стандартного конструктора, он предоставляет конечный маркер, который вы можете использовать в операциях сравнения для определения момента завершения просмотра каталога. Поэтому используйте следующий оператор.

directory_iterator end;

Затем вы можете создать итератор для вашего пути и следующим образом сравнивать его с маркером конца.

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

 // выполнить любые действия с *it

 std::cout << it->leaf();

}

Функция-член leaf возвращает строку, представляющую конечный элемент пути, а не весь путь, который вы можете получить, вызывая функцию-член string.

Если вам требуется обеспечить переносимость, но по каким-то причинам вы не можете использовать библиотеки Boost, обратите внимание на исходный код Boost. Он содержит операторы #ifdef, которые учитывают (по большей части) отличия среды Windows и ОС, использующих интерфейс Posix, и в частности отличия в представлении путей, например буквы дисководов и имена устройств.

Смотри также

Рецепты 10.10 и 10.11.

10.13. Извлечение расширения файла из строки

Проблема

Имеется имя файла или полный путь и требуется получить расширение файла, которое является частью имени файла, расположенной за последней точкой. Например, в именах файлов src.cpp, Window.class и Resume.doc

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату