Вступление
Краткое
описание хидера
Класс 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 применимы ко всем функциям членам классов и свободным, которые определены в данном хидере.
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 реализует соответствующий стандартному входной итератор, через который можно получать доступ к каталогу.
Итератор указывает на объекты типа 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++, за исключением следующих моментов:
char*,
для улучшения платформонезависимости.Объяснение: Функции, которые уже существуют в стандартной библиотеке C++, такие как remove() и rename(), реализованы в Boost.Filesystem с такими же именами и поведением, чтобы исключить сюрпризы для программиста.
Объяснение: Некоторые ошибки, которые на первый взгляд должны фиксироваться предусловиями, не специфицированы таковыми, а вместо этого генерируют исключения. Причина заключается в возможности ситуации race-conditions (гонки за ресурсами несколькими птоками исполнения), что делает ненадежной стратегию проверки предусловий перед вызовом функций. Согласно принятой практике дизайна библиотеки, предусловия не задаются, когда неразумно проверять их перед вызовом функции.
Объяснение для пустых путей: Некоторые ошибки, в частности пустые пути в качестве аргумента функции, описаны в разделах и Предусловия и Исключения. Не пустой путь в качестве предусловия фигурирует потому, что пустой путь почти наверняка означает ошибку. Эта ошибка удовлетворяет обычным критериям для Предусловий как описано в стандарте C++, и предварительное обнаружение данной ошибки пользователем не сталкивается с проблемой precondition race. Данная проверка также описана в разделе Throws, чтобы гарантировать, что ошибочные результаты хорошо определены и не зависят от реализации, а также потому, что существующая практика для таких же функций в API ОС заключается в признании пустых путей ошибочными. Поскольку библиотека Boost.Filesystem предназначена изначально для написания скриптов на C++, то неопределенное поведение при ошибках неприемлемо.
Объяснение для названия: См. объяснение названия для класса path.
bool exists( const path & ph );
Возвращает: true, если ОС подтверждает существование пути ph, иначе false.
Замечение:
Даже если exists( ph ) == true, нет гарантии,
что можно выполнять с файлом или каталогом другие операции.
Права доступа или другие аспекты безопасности могут вызвать сбой других операций
с данным файлом или каталогом.
Замечение: Использование exists("")
корректно и возвращает false
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
(является_символической_ссылкой).
Не-генерирование исключение позволяет использовать функцию во всех четырех
случаях:
ph не существует: !exists(ph) && !symbolic_link_exists(ph)
ph существует и не является символической
ссылкой: exists(ph) &&
!symbolic_link_exists(ph)
ph существует и является символической ссылкой
на несуществующий файл или каталог: !exists(ph) && symbolic_link_exists(ph)
ph существует и является символической ссылкой
на существующий файл или каталог: exists(ph) && symbolic_link_exists(ph)
bool is_directory( const path & ph );
Возвращает: true если ОС подтверждает, что путь ph это каталог, иначе false.
Генерирует исключения: if !exists(ph)
Объяснение: Генерация исключения при !exists(ph)
вместо возврата значения false
применена потому, что в
реальном коде !exists(ph) первой обнаруживает программную ошибку. Составная
функция exists(ph) && is_directory(ph) всегда может быть
добавлена дополнительно.
bool is_empty( const path & ph );
Возвращает: true если ОС подтверждает, что путь, представленный аргументом ph это пустой файл или каталог, иначе false.
Генерирует исключения: if !exists(ph)
Эта функция определяет, является ли файл или каталог, на который указывает путь ph, пустым. Для определения, что строка пути сама является пустой, нужно использовать метод path::empty().
Предупреждение: Отметки времени, ассоциируемые с файлами, трактуются немного по разному для разных типов файловых системы. Для некоторых системах точность ограничена одним часом. Многие программы одновременно работают с файловыми системами 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
не описывается как послеусловие, потому что
установленная метка времени может отличаться от текущего системного времени на
некоторое значение для некоторых ОС.
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/"..")). См.
объяснение для пустых путей.
bool remove( const path & ph );
Предусловие: !ph.empty()
Возвращает: результат exists( ph )
перед проверкой послеусловия.
Послеусловие: !exists( ph )
Генерирует исключения: если ph.empty() || (exists(ph) && is_directory(ph) &&
!is_empty(ph)). См. объяснение для пустых
путей.
Замечение: Символические ссылки удаляются сами, вместо того, чтобы удалять объекты, на которые они ссылаются.
Объяснение: нет генерации исключений при !exists( ph )
так как без генерации:
ph это
'висячая" симолическая
ссылка. Имеется, однако, некоторое ухудшение надежности, так как некоторые ошибки будут пропущены, хотя в другом случае они были бы зафиксированы. К примеру, написанный с опечаткой путь останется незамеченным долгое время.
Первоначальная версия библиотеки генерировала исключение, когда путь не существовал. Теперь это поведение изменено из-за жалоб пользователей.
unsigned long remove_all( const path & ph );
Предусловие:: !ph.empty()
Послеусловие: !exists( ph ) && !symbolic_link_exists( ph )
Возвращает: Число удаленных файлов и каталогов.
Генерирует исключения:: если ph.empty(). См.
объяснение для пустых путей.
Замечение: Символические ссылки удаляются сами, вместо того, чтобы удалять объекты, на которые они ссылаются.
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 между корнями.
Замечениеие: Символические ссылки переименовываются сами, вместо того, чтобы переименовывать файлы и каталоги, на которые они указывают.
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.
const path & initial_path();
Эффекты: При первом вызове запоминает путь, который возвращается функцией current_path().
Предпочтительной реализацией будет вызов initial_path() при инициализации программы до вызова main(), однако это может быть невозможным для некоторых реализаций библиотеки времени исполнения языка C++.
Возвращает: Ссылку на сохраненный путь.
Объяснение: Фактически, данная функция превращает опасную глобальную переменную в более безопасную глобальную константу. Предпочтительная реализация требует поддержки со стороны библиотеки времени исполнения, поэтому для платформ, где невозможно изменить существующую библиотеку времени исполнения, есть альтернативная реализация.
Замечение: Хорошей практикой для программ, которые зависят от работы функции initial_path(), является вызов этой функции сразу после входа в main(). Это защитит код от изменения текущего каталога другой функцией, вызывающей API ОС до вызова initial_path().
path current_path();
Возвращает: текущий путь, хранимый операционной системой.
Послеусловие: current_path().is_complete()
Замечение: Эквивалентная функция в POSIX это getcwd(). В MS Windows это функция GetCurrentDirectoryA().
Предупреждение: Текущий путь, который хранится операционной системой, это по сути опасная глобальная переменная. Ее значение может меняться непредсказуемо при работе других программ или вызове функций API. Более безопасной альтернативой является функция initial_path().
Объяснение: Будучи опасной, данная функция остается полезной для других библиотек. Имя current_path() было выбрано, чтобы подчеркнуть, что функция возвращает полный (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() |
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().
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