Библиотека Boost C++ Filesystem: хидер <operations.hpp>

Вступление
     Краткое описание хидера
     Класс directory_iterator
         Конструкторы
         Деструктор
         Другие функции
     Функции для различных операций
         exists
         symbolic_link_exists
         is_directory
         is_empty
         last_write_time
         create_directory
         remove
         remove_all
         rename
         copy_file
         initial_path
         complete
         system_complete

Вступление

Хидер boost/filesystem/operations.hpp cодержит объявления инструментов для выполнения различных операций с файлами и каталогами.

Эти операции выполняются над путями; см. документацию к хидеру boost/filesystem/path.hpp.

О потоках ввода-вывода см. документацию к хидеру boost/filesystem/fstream.hpp.

Общие спецификации библиотеки Boost.Filesystem применимы ко всем функциям членам классов и свободным, которые определены в данном хидере.

Краткое описание хидера boost/filesystem/operations.hpp

namespace boost
{
  namespace filesystem
  {

    class directory_iterator
    {
    public:
      typedef path                     value_type;
      typedef std::ptrdiff_t           difference_type;
      typedef const path *             pointer;
      typedef const path &             reference;
      typedef std::input_iterator_tag  iterator_category;

      directory_iterator();
      explicit directory_iterator( const path & directory_ph );

      // other functions
      // ...
    };

    bool exists( const path & ph );
    bool symbolic_link_exists( const path & ph );
    bool is_directory( const path & ph );
    bool is_empty( const path & ph );
    std::time_t last_write_time( const path & ph );
    void last_write_time( const path & ph, std::time_t new_time );

    void create_directory( const path & directory_ph );
    bool remove( const path & ph );
    unsigned long remove_all( const path & ph );
    void rename( const path & from_path,
                 const path & to_path );
    void copy_file( const path & source_file,
                    const path & target_file );

    const path & initial_path();
    path current_path();
    path complete( const path & ph,
                   const path & base = initial_path() );
    path system_complete( const path & ph );

  } // namespace filesystem
} // namespace boost

Класс directory_iterator

Класс directory_iterator реализует соответствующий стандартному входной итератор, через который можно получать доступ к каталогу.

Итератор указывает на объекты типа boost::filesystem::path, поэтому разыменование объекта класса directory_iterator дает путь к файлу или подкаталогу, содержащемуся в каталоге, который соответсвует аргументу, переданному в конструктор итератора. Путь, который получается при разыменовании directory_iterator, составляется прибавлением имени каталога к пути, указанному как аргумент конструктора.

Порядок, в котором перечисляются элементы в каталоге с помощью directory_iterator не определен. Поэтому привязка к какому-либо порядку, обеспечиваемому конкретной реализацией, приведет к непортабельному коду.

Путь, который получается при разыменовании directory_iterator, если представляет имя каталога, может быть использован как аргумент функций библиотеки Boost.Filesystem, которые работают с путями. Если путь не представляет имя каталога, то он может также быть использован в функциях стандартной библиотеки C++, получающих в качестве аргумента имя файла. Результат разыменования directory_iterator никогда не принимает значений ".." или "."t;.

Замечение: Вышесказанное означает, что если каталоги в ОС могут содержать элементы, которые нельзя использовать функциями библиотеки Boost.t.Filesystem или стандартной библиотеки C++, то эти элементы будут пропущены при просмотре каталога итератором. Такие элементы по определению не портабельные, но ним всегда можно обратиться посредством API конкретной ОС, если это необходимо.

Предупреждениеие: Программы, просматривающие каталоги, могут нуждаться в проверке, посредством exists(), существования результата разыменования. Это может быть символическая ссылка на несуществующий файл или каталог. Программы, которые рекурсивно обходят дерево каталогов для удаления или переименования элементов, могут нуждаться в специальных проверках, чтобы избегать символические ссылки (к примеру, с помощью symbolic_link_exists()).

Предупреждение: Если подкаталог или файл удаляется после того, как отработал конструктор directory_iterator для данного каталога, то неопределено, появятся ли удаленные элементы среди результатов итерации по содержимому каталога.

Конструкторы

directory_iterator();

Эффекты: создает объект класса directory_iterator имеющий значение после-окончания, как предписано стандартом C++ раздел 24.1.

explicit directory_iterator( const path & directory_ph );

Эффекты: создает объект класса directory_iterator имеющий значение первого элемента в directory_ph, или если empty(directory_ph), то значение после-окончания.

Генерирует исключения: if !exists( directory_ph )

Замечение: Чтобы пройти по содержимому текущего каталога, следует писать directory_iterator(current_path()), а не directory_iterator("").

Другие функции

Класс directory_iterator также реализует все функции, которые требуются для входных итераторов согласно стандарту C++, такие как operator==, operator++, и operator*.

Функции не-члены класса

Свободные функции (не члены класса) выполняют общие операции с файлами и каталогами. Они следуют обычной практике стандартных библиотек C и C++, за исключением следующих моментов:

Объяснение: Функции, которые уже существуют в стандартной библиотеке C++, такие как remove() и rename(), реализованы в Boost.Filesystem с такими же именами и поведением, чтобы исключить сюрпризы для программиста.

Объяснение: Некоторые ошибки, которые на первый взгляд должны фиксироваться предусловиями, не специфицированы таковыми, а вместо этого генерируют исключения. Причина заключается в возможности ситуации race-conditions (гонки за ресурсами несколькими птоками исполнения), что делает ненадежной стратегию проверки предусловий перед вызовом функций. Согласно принятой практике дизайна библиотеки, предусловия не задаются, когда неразумно проверять их перед вызовом функции.

Объяснение для пустых путей: Некоторые ошибки, в частности пустые пути в качестве аргумента функции, описаны в разделах и Предусловия и Исключения. Не пустой путь в качестве предусловия фигурирует потому, что пустой путь почти наверняка означает ошибку. Эта ошибка удовлетворяет обычным критериям для Предусловий как описано в стандарте C++, и предварительное обнаружение данной ошибки пользователем не сталкивается с проблемой precondition race. Данная проверка также описана в разделе Throws, чтобы гарантировать, что ошибочные результаты хорошо определены и не зависят от реализации, а также потому, что существующая практика для таких же функций в API ОС заключается в признании пустых путей ошибочными. Поскольку библиотека Boost.Filesystem предназначена изначально для написания скриптов на C++, то неопределенное поведение при ошибках неприемлемо.

Объяснение для названия: См. объяснение названия для класса path.

exists

bool exists( const path & ph );

Возвращает: true, если ОС подтверждает существование пути ph, иначе false.

Замечение: Даже если exists( ph ) == true, нет гарантии, что можно выполнять с файлом или каталогом другие операции. Права доступа или другие аспекты безопасности могут вызвать сбой других операций с данным файлом или каталогом.

Замечение: Использование exists("") корректно и возвращает false

symbolic_link_exists

bool symbolic_link_exists( const path & ph );

Возвращает: true если ОС подтверждает, что представленный аргументом ph путь существует и является символической ссылкой, иначе false.

Замечение: См. предупреждение для directory iterator в одном из случаев использования symbolic_link_exists().

Замечение: ОС Microsoft Windows в настоящее время не поддерживает символические ссылки, так что для этой платформы symbolic_link_exists() всегда возвращает false. (Файлы ярлычков  short-cut с расширением .lnk не поддерживаются непосредственно ОС, а только некоторыми программами - к примеру Explorer'ом). Но несмотря на это, программисты должны проверять наличие символических ссылок на случай, что данная возможность будет добавлена в MS Windows, а также чтобы обеспечить портабельность программ для POSIX систем, где символические ссылки могут быть.

Объяснение: Функция не генерирует исключение, если ph не существует, и поэтому названа symbolic_link_exists (т.е существует_символическая_ссылка), а не is_symbolic_link (является_символической_ссылкой). Не-генерирование исключение позволяет использовать функцию во всех четырех случаях:

is_directory

bool is_directory( const path & ph );

Возвращает: true если ОС подтверждает, что путь ph это каталог, иначе false.

Генерирует исключения: if !exists(ph)

Объяснение: Генерация исключения при !exists(ph) вместо возврата значения false применена потому, что в реальном коде !exists(ph) первой обнаруживает программную ошибку. Составная функция exists(ph) && is_directory(ph) всегда может быть добавлена дополнительно.

is_empty

bool is_empty( const path & ph );

Возвращает: true если ОС подтверждает, что путь, представленный аргументом ph это пустой файл или каталог, иначе false.

Генерирует исключения: if !exists(ph)

Эта функция определяет, является ли файл или каталог, на который указывает путь ph, пустым. Для определения, что строка пути сама является пустой, нужно использовать метод path::empty().

last_write_time

Предупреждение: Отметки времени, ассоциируемые с файлами, трактуются немного по разному для разных типов файловых системы. Для некоторых системах точность ограничена одним часом. Многие программы одновременно работают с файловыми системами FAT, ISO9660, NTFS, и POSIX, сталкиваясь с разным поведением функции last_write_time. В течение работы программы системные часы могут быть установлены в новое значение другим, возможно автоматическим, процессом. Другой поток или процесс может выполнить запись в файл, неожиданно изменив метку последней записи  файла.

std::time_t last_write_time( const path & ph ););

Возвращает: время последней модификации файла, возвращаемое операционной системой. Если это время не может быть определено, то возвращается значение (std::time_t)(-1).

Для преобразования возвращенной величины в UTC или локальное (местное) время, используйте функции std::gmtime() or std::localtime() соответственно.

Генерирует исключения: если !exists(ph)

void last_write_time( const path & ph, std::time_t new_time );

Эффекты: С помощью вызова API ОС устанавливает время последней записи для указанного файла в new_time, или в текущее время если new_time==std::time_t().

Генерирует исключения: если !exists(ph)

Объяснение: last_write_time(ph)==new_time не описывается как послеусловие, потому что установленная метка времени может отличаться от текущего системного времени на некоторое значение для некоторых ОС.

create_directory

void create_directory( const path & directory_ph );

Предусловие: !directory_ph.empty()

Послеусловие: exists(directory_ph) && is_directory(directory_ph) && is_empty(directory_ph)

Генерирует исключения: если directory_ph.empty() || exists(directory_ph)) || !exists(directory_ph/"..")). См. объяснение для пустых путей.

remove

bool remove( const path & ph );

Предусловие: !ph.empty()

Возвращает: результат exists( ph ) перед проверкой послеусловия.

Послеусловие: !exists( ph )

Генерирует исключения: если ph.empty() || (exists(ph) && is_directory(ph) && !is_empty(ph)). См. объяснение для пустых путей.

Замечение: Символические ссылки удаляются сами, вместо того, чтобы удалять объекты, на которые они ссылаются.

Объяснение: нет генерации исключений при !exists( ph ) так как без генерации:

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

Первоначальная версия библиотеки генерировала исключение, когда путь не существовал. Теперь это поведение изменено из-за жалоб пользователей.

remove_all

unsigned long remove_all( const path & ph );

Предусловие:: !ph.empty()

Послеусловие: !exists( ph ) && !symbolic_link_exists( ph )

Возвращает: Число удаленных файлов и каталогов.

Генерирует исключения:: если ph.empty(). См. объяснение для пустых путей.

Замечение: Символические ссылки удаляются сами, вместо того, чтобы удалять объекты, на которые они ссылаются.

rename

void rename( const path & source, const path & target );

Предусловие: !source.empty() && !target.empty()

Эффекты: Изменяет имя исходного файла или каталога source на заданное target. Точнее говоря:

Source Target Результат будет таким, как если бы выполнены такие действия
!exists()   генерирует filesystem_error. Обратите внимание, что !exists() включает в себя случай source.empty().
  target.empty() генерирует filesystem_error. См. объяснение для функции create_directory().
  exists() && !is_directory() генерирует filesystem_error.
!is_directory() !exists() если !exists( target / ".." ), то генерирует filesystem_error. Иначе имя source.leaf() меняется на target.leaf(), и если source / ".." указывает на отличный от target / ".." каталог, то переименованный файл перемещается туда.
!is_directory() is_directory() Файл source перемещается в каталог target.
is_directory() !exists() Если !exists( target / ".." ), то генерируется filesystem_error. Иначе, имя source.leaf() меняется на target.leaf(), и если system_complete(source.banch_path()) указывает на отличный от system_complete(target.branch_path()) каталог,  то переименованный каталог перемещается туда.
is_directory() is_directory() Каталог source перемещается из source / ".." в каталог target, становясь его подкаталогом.

Послеусловие: !exists(source) && exists(target), и атрибуты и содержимое файла или каталога source остаются неизменными.

Генерирует исключения: См. таблицу результатов выше. См. объяснение для пустых путей.

Объяснение: Так функция rename выполняет по сути ту же операцию, что и move, то отдельной функции move в библиотеке нет. Выбор имени основывается на существующей практике в библиотеках C, C++, и POSIX, а также потому, что имя move неявно подразумевает физическое перемещение файлов, что не обязательно имеет место.

Замечение: Некоторые ОС с многими корнями не позволяют выполнять операцию rename между корнями, и попытки вызвать функцию rename в этих случаях приведет к генерации исключения filesystem_error. Разработчики не должны предпринимать героических усилий, к примеру пытаться ввести копирование файлов, в реализациях библиотеки Boost.Filesystem для того, чтобы в таких случаях заставлять работать функцию rename между корнями.

Замечениеие: Символические ссылки переименовываются сами, вместо того, чтобы переименовывать файлы и каталоги, на которые они указывают.

copy_file

void copy_file( const path & source_file, const path & target_file );

Предусловие: !source.empty() && !target.empty()

Эффекты: Копирует файл с именем source_file в target_file.

Генерирует исключения: если !exists(source_file) || is_directory(source_file) || exists(target_file) || target_file.empty() || !exists(to_file_path/"..")). См. объяснение для пустых путей.

Замечение: Атрибуты файлов также копируются. В частности, структуры POSIX stat::st_mode, и Windows BY_HANDLE_FILE_INFORMATION::dwFileAttributes.

initial_path

const path & initial_path();

Эффекты: При первом вызове запоминает путь, который возвращается функцией current_path().

Предпочтительной реализацией будет вызов initial_path() при инициализации программы до вызова main(), однако это может быть невозможным для некоторых реализаций библиотеки времени исполнения языка C++.

Возвращает: Ссылку на сохраненный путь.

Объяснение:  Фактически, данная функция превращает опасную глобальную переменную в более безопасную глобальную константу. Предпочтительная реализация требует поддержки со стороны библиотеки времени исполнения, поэтому для платформ, где невозможно изменить существующую библиотеку времени исполнения, есть альтернативная реализация.

Замечение: Хорошей практикой для программ, которые зависят от работы функции initial_path(), является вызов этой функции сразу после входа в main(). Это защитит код от изменения текущего каталога другой функцией, вызывающей API ОС до вызова initial_path().

current_path

path current_path();

Возвращает: текущий путь, хранимый операционной системой.

Послеусловие: current_path().is_complete()

Замечение: Эквивалентная функция в POSIX это getcwd(). В MS Windows это функция GetCurrentDirectoryA().

Предупреждение: Текущий путь, который хранится операционной системой, это по сути опасная глобальная переменная. Ее значение может меняться непредсказуемо при работе других программ или вызове функций API. Более безопасной альтернативой является функция initial_path().

Объяснение: Будучи опасной, данная функция остается полезной для других библиотек. Имя current_path() было выбрано, чтобы подчеркнуть, что функция возвращает полный (complete) путь, а не только имя каталога.

complete

path complete( const path & ph, const path & base = initial_path() );

Предусловие: !ph.empty() && base.is_complete() && (ph.is_complete() || !ph.has_root_name())

Эффекты: Составляет полный путь (complete path) из ph и base, используя следующие правила:

Для ОС с одним корнем (POSIX-системы, к примеру), если ph.empty() или ph.is_complete(), то в итоге возвращается ph, иначе возвращается base/ph.

Для ОС с многими корнями (Windows, Classic Mac, многие другие), правила даны в таблице:

  ph.has_root_directory() !ph.has_root_directory()
ph.has_root_name() ph (precondition failure)
!ph.has_root_name() base.root_name()
/ ph
base / ph

Возвращает: скомпонованный путь.

Послеусловие: для возвращенного пути p, вызов  p.is_complete() возвращает true.

Генерирует исключения: Если не выполнены предусловия. См. объяснение для пустых путей.

Замечание: когда необходима платформонезависимость, следует использовать функцию complete(). Когда требуется специфичное для конкретной ОС поведение, надо использовать функцию system_complete().

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

Зависящее от ОС поведение предпочтительно, когда выполняются операции с путями, получаемыми от пользователя, либо если пути печатаются для пользователя. Тестовая программа simple_ls.cpp, к примеру, работает с путями, заданными в родном для ОС формате, поэтому использует вызов system_complete() для гарантии, что пути ведут себя корректно для конкретной ОС.

Объяснение: Порция предусловия !ph.has_root_name() запрещает, чтобы условие проверки of ph.root_name() было не равно to base.root_name(). Это ограничение шире< чем можно было бы ожидать, так как запрещает случаи, когда они на самом деле эквивалентны. Однако не существует портабельного способа выразить требования эквивалентности root_name().

system_complete

path system_complete( const path & ph );

Предусловие: !ph.empty()

Эффекты: Создает полный (complete) путь из ph, используя те же самые правила, которые применяет ОС для приведения путей, заданных как аргументы - имена файлов - в стандартной функции open.

Для POSIX-систем, system_complete( ph ) имеет такую же семантику, как complete( ph, current_path() ).

Для Windows, функция system_complete( ph ) имеет такую же семантику, как complete( ph, current_path() ) если ph.is_complete() || !ph.has_root_name() или ph и base имеют одинаковый root_name(). В противном случае функция работает как complete( ph, kinky ), где kinky это текущий каталог для диска ph.root_name(). Это будет последнее установленное значение текущего каталога для данного диска, и поэтому может может быть установлено предыдущей программой! Хотя такая семантика зачастую полезна, это может вызвать множество ошибок, и поэтому заслуживает названия "kinky" - странный, извращенный.

Возвращает:: Скомпонованный путь.

Послеусловие: для возвращенного пути p значение p.is_complete() равно true.

Генерирует исключения: Если ph.empty(). См. объяснение для пустых путей.

Замечение: См. замечание о функции complete() для предложений по использованию.

Предупреждение: Данная функция использует глобальную переменную (current_path()), и поэтому является более опасной, чем похожая функция complete(). Эта функция вдвойне опасна в Windows, где при определенных условиях работы с разными дисками она может использовать значение текущего каталога, установленное предыдущей программой, запущенной командным процесором.


© Copyright Beman Dawes, 2002

Use, modification, and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txtxt)

последняя правка: 10.06.2005

библиотека BOOST C++ http://www.boost.org
перевод Elijah Koziev www.solarix.ru

  © Mental Computing 2010