Introduction
Header synopsis
Class directory_iterator
Constructors
Destructor
Other functions
Non-member functions
exists
is_directory
is_empty
create_directory
remove
remove_all
rename
copy_file
initial_directory
The boost/filesystem/operations.hpp header provides operations on files and directories.
These operations traffic in paths; see boost/filesystem/path.hpp documentation.
For file I/O streams, see boost/filesystem/fstream.hpp documentation.
As with all Filesystem Library components, errors may result in filesystem_error or std::bad_alloc exceptions being thrown. See Requirements.
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 is_directory( const path & ph ); bool is_empty( const path & ph ); void create_directory( const path & directory_ph ); void 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 & from_file_ph, const path & to_file_ph ); const path & initial_directory(); } // namespace filesystem } // namespace boost
Class directory_iterator provides a C++ standard conforming input iterator which accesses the contents of a directory.
The value type is boost::filesystem::path, so dereferencing a directory_iterator yields a path to a file or directory contained within the directory represented by the directory-path argument supplied at construction. The path returned by dereferencing a directory_iterator is composed by appending the name of the directory entry to the directory path supplied at construction.
The order of the path entries returned by dereferencing successive increments of a directory_iterator is unspecified. Thus depending on the ordering provided by a particular implementation will result in non-portable code.
A path returned by dereferencing a directory_iterator is, if
representing a directory, suitable for use as an argument to Filesystem Library
functions specified as accepting paths or directory paths. If not representing a
directory, the dereferenced path is suitable for use as an argument to
Filesystem Library functions specified as accepting paths or file paths, or C++
Standard Library functions specified as taking file names. The leaf of a path
returned by dereferencing a directory_iterator will never be ".."
or "."
.
Note: The implication of the above requirement is that if an operating system's directories can contain entries which are not usable by Filesystem Library or Standard Library functions, these entries will be skipped during directory iteration. Such entries are by definition non-portable, but can always be accessed via the native operating system API if required.
directory_iterator();
Effects: Constructs a directory_iterator having the past-the-end value as described in the C++ standard, section 24.1.
explicit directory_iterator( const path & directory_ph );
Effects: Constructs a directory_iterator with a value representing the first path in directory_ph, or if
empty(directory_ph)
, the past-the-end value.
Class directory_iterator also supplies all the other functions required by the C++ standard clause 24 for input iterators, such as operator==, operator++, and operator*.
The non-member functions provide common operations on files and directories. They follow traditional practice of the C and C++ standard libraries, except that they:
char*
's, for much
enhanced portability.Rationale: Functions which already exist in the C++ Standard Library, such as remove() and rename(), retain the same names and general behavior in the Filesystem Library, to minimize surprises.
Rationale: Errors which might appear to be preconditions are not specified as such, but instead are specified to throw exceptions. This is because the possibility of race-conditions makes it unreliable to test for preconditions before calling the function. As a design practice, preconditions should always be testable by a program, so that violations can be avoided. It is not always possible or desirable to abstract away the fact that the library is implemented by calls to the operating system, and this is one of those cases.
Naming Rationale: See class path Naming Rationale.
bool exists( const path & ph );
Returns: True if the operating system reports the path represented by ph exists, else false.
Note: Even if exists( ph ) == true, there is no guarantee that it will be possible to perform other operations on the file or directory. Access rights or other security concerns, for example, may cause other operations to fail.
bool is_directory( const path & ph );
Returns: True if the operating system reports the path represented by ph is a directory, else false.
Throws: if
!exists(ph)
Rationale: Treating
!exists(ph)
as an exception rather than just returning false came about because in real code!exists(ph)
has often been the first indicate of a programming error. A compound function returningexists(ph) && is_directory(ph)
can always be added later.
bool is_empty( const path & ph );
Returns: True if the operating system reports the path represented by ph is an empty file or empty directory, else false.
Throws: if
!exists(path)
void create_directory( const path & directory_ph );
Postcondition:
exists(directory_ph) && is_directory(directory_ph) && is_empty(directory_ph)
Throws: if
exists(directory_ph)) || !exists(branch(directory_ph))
void remove( const path & ph );
Postcondition:
!exists( ph )
Throws: if
exists(ph) && is_directory(ph) && !is_empty(ph)
Rationale: Does not throw when
!exists( ph )
because not throwing is:
- Slightly easier-to-use for many common use cases.
- Slightly higher-level because it implies use of postcondition semantics rather than effects semantics, which would be specified in the somewhat lower-level terms of interactions with the operating system.
There is, however, a slight decrease in safety because some errors will slip by which otherwise would have been detected. For example, a misspelled path name could go undetected for a long time.
The initial version of the library did throw when the path did not exist; it was changed only reluctantly.
unsigned long remove_all( const path & ph );
Postcondition:
!exists( ph )
Returns: The number of files and directories removed.
void rename( const path & from_ph, const path & to_ph );
Effects: Changes the name of file or directory from_ph to to_ph.
Postconditions:
!exists(from_ph) && exists(to_ph)
, and the file or directory contents and attributes are otherwise unchanged.Throws: if
!exists(from_ph) || exists(to_ph) || !exists(branch(to_ph))
Rationale: Because rename is logically the same operation as move, there is no need for a separate move function. The choice of the name is inherited from the C Library.
Note: If
branch(from_path)
resolves to the same directory asbranch(to_ph)
, thenleaf(from_ph)
must not be the same name asleaf(to_ph)
, but if the branch directories are different, it doesn't matter if the leaf names are the same.Note: Some operating systems with multi-rooted file systems representing different drives, devices, or volumes, do not allow rename operations between roots . Implementations should not take heroic efforts, such as switching to a copy mode, to make an otherwise failing rename succeed across drives, devices, or volumes.
void copy_file( const path & from_file_ph, const path & to_file_ph );
Effects: Copies the file represented by from_file_ph to to_file_ph.
Throws: if
!exists(from_file_ph) || directory(from_file_ph) || exists(to_file_ph) || !exist(branch(to_path))
const path & initial_directory();
Effects: The first time the function is called, stores an absolute directory path.
The preferred value for the stored path is the initial working directory path when main() was called. Implementations are permitted, however, to store the current working directory at the time of the first call to initial_directory(). If neither of these actions is possible, a diagnostic is required.
Returns: The stored path.
Rationale: The semantics, in effect, turn a global variable into a safer global constant. The preferred implementation requires runtime library support, so alternate semantics are supplied for those implementations which cannot change an existing the runtime library.
Note: It would be good practice in a program dependent on initial_directory() to call it immediately upon entering main(). That protects against another function altering the current working directory (using a native platform function) before the first call to initial_directory().
© Copyright Beman Dawes, 2002
Revised 22 September, 2002