Читаем C++17 STL Стандартная библиотека шаблонов полностью

1. Сначала включим все необходимые заголовочные файлы и объявим об использовании пространств имен std и filesystem:

#include

#include

#include

#include

#include

using namespace std;

using namespace filesystem;

2. Затем реализуем вспомогательную функцию, которая принимает в качестве аргумента directory_entry и возвращает его размер в файловой системе. Это не каталог, мы просто вернем размер файла, вычисленный с помощью file_size:

static size_t entry_size(const directory_entry &entry)

{

  if (!is_directory(entry)) { return file_size(entry); }

3. Если это каталог, то нужно проитерировать по всем его записям и подсчитать их размер. Мы будем вызывать вспомогательную функцию entry_size рекурсивно при повторной встрече с подкаталогами:

  return accumulate(directory_iterator{entry}, {}, 0u,

        [](size_t accum, const directory_entry &e) {

    return accum + entry_size(e);

  });

}

4. Для повышения читабельности воспользуемся функцией size_string, которая уже встречалась в этой главе. Она просто сокращает большие размеры файлов, делая их «аккуратнее» и добавляя префиксы «кило», «мега» или «гига»:

static string size_string(size_t size)

{

  stringstream ss;

  if        (size >= 1000000000) {

    ss <<   (size / 1000000000) << 'G';

  } else if (size >= 1000000) {

    ss <<   (size / 1000000) << 'M';

  } else if (size >= 1000) {

    ss <<   (size / 1000) << 'K';

  } else { ss << size << 'B'; }

  return ss.str();

}

5. Первое, что нужно сделать в функции main, — проверить, предоставил ли пользователь путь к файлу в командной строке. Если это не так, то возьмем текущий каталог. Прежде чем продолжить, проверим, существует ли данный каталог:

int main(int argc, char *argv[])

{

  path dir {argc > 1 ? argv[1] : "."};

  if (!exists(dir)) {

    cout << "Path " << dir << " does not exist.\n";

    return 1;

}

6. Теперь можно проитерировать по всем записям каталога и вывести на экран их имена и размер:

  for (const auto &entry : directory_iterator{dir}) {

    cout << setw(5) << right

         << size_string(entry_size(entry))

         << " " << entry.path().filename().c_str()

         << '\n';

  }

}

7. Компиляция и запуск программы дадут следующий результат. Я запустил ее для каталога, в котором находится офлайн-справка по С++. Поскольку он содержит и подкаталоги, наша вспомогательная функция, суммирующая размер файла, очень пригодится:

$ ./file_size ~/Documents/cpp_reference/en/

 19M c

 12K c.html

147M cpp

 17K cpp.html 22K index.html

 22K Main_Page.html

Как это работает

Вся программа строится на использовании функции file_size для обычных файлов. Если программа увидит каталог, то рекурсивно спустится в него и вызовет функцию file_size для всех его записей.

Единственное, что мы сделали для определения того, можем ли вызвать непосредственно file_size или нужно рекурсивно спуститься дальше, — реализовали предикат is_directory. Он работает для каталогов, которые содержат только обычные файлы и каталоги.

Поскольку наша программа довольно проста, она даст сбой при следующих условиях.

□ Функция file_size работает только для обычных файлов и символьных ссылок. Она генерирует исключение во всех других случаях.

□ Несмотря на то что функция file_size работает для символьных ссылок, она все еще сгенерирует исключение, если мы вызовем ее для неработающей символьной ссылки.

Чтобы сделать программу из нашего примера более надежной, следует воспользоваться защитным программированием в случаях неверных типов файлов и обработки исключений. 

<p id="AutBody_Root128"><strong>Подбиваем статистику о типах файлов</strong></p>

В предыдущем примере мы реализовали инструмент, который выводит на экран размер всех членов каталога.

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

Как это делается

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

Все книги серии Библиотека программиста

Программист-фанатик
Программист-фанатик

В этой книге вы не найдете описания конкретных технологий, алгоритмов и языков программирования — ценность ее не в этом. Она представляет собой сборник практических советов и рекомендаций, касающихся ситуаций, с которыми порой сталкивается любой разработчик: отсутствие мотивации, выбор приоритетов, психология программирования, отношения с руководством и коллегами и многие другие. Подобные знания обычно приходят лишь в результате многолетнего опыта реальной работы. По большому счету перед вами — ярко и увлекательно написанное руководство, которое поможет быстро сделать карьеру в индустрии разработки ПО любому, кто поставил себе такую цель. Конечно, опытные программисты могут найти некоторые идеи автора достаточно очевидными, но и для таких найдутся темы, которые позволят пересмотреть устоявшиеся взгляды и выйти на новый уровень мастерства. Для тех же, кто только в самом начале своего пути как разработчика, чтение данной книги, несомненно, откроет широчайшие перспективы. Издательство выражает благодарность Шувалову А. В. и Курышеву А. И. за помощь в работе над книгой.

Чед Фаулер

Программирование, программы, базы данных / Программирование / Книги по IT

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

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных