boost/filesystem/operations.hpp

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

Introduction

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.

Header boost/filesystem/operations.hpp synopsis

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

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.

Constructors

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.

Other functions

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*.

Non-member functions

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:

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.

exists

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.

is_directory

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 returning exists(ph) && is_directory(ph) can always be added later.

is_empty

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)

create_directory

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))

remove

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:

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.

remove_all

unsigned long remove_all( const path & ph );

Postcondition: !exists( ph )

Returns: The number of files and directories removed.

rename

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 as branch(to_ph), then leaf(from_ph) must not be the same name as leaf(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.

copy_file

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))

initial_directory

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