mirror of
https://github.com/boostorg/filesystem.git
synced 2025-05-12 05:31:49 +00:00
288 lines
15 KiB
HTML
288 lines
15 KiB
HTML
<html>
|
||
|
||
<head>
|
||
<meta http-equiv="Content-Language" content="en-us">
|
||
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||
<title>Boost Filesystem Library</title>
|
||
</head>
|
||
|
||
<body bgcolor="#FFFFFF">
|
||
|
||
<h1>
|
||
<img border="0" src="../../../c++boost.gif" align="center" width="277" height="86">Boost
|
||
Filesystem Library</h1>
|
||
<table border="0" cellpadding="0" width="100%">
|
||
<tr>
|
||
<td width="50%" valign="top"><font size="4">This Document</font><br>
|
||
<a href="#Introduction">Introduction</a><br>
|
||
<a href="#tutorial">Two-minute tutorial</a><br>
|
||
<a href="#Examples">Examples</a><br>
|
||
|
||
<a href="#Definitions">Definitions</a><br>
|
||
|
||
<a href="#Requirements">Requirements</a><br>
|
||
<a href="#Race-condition">Race-condition danger</a><br>
|
||
<a href="#Acknowledgements">Acknowledgements</a></td>
|
||
<td width="50%"><font size="4">Other Documents</font><br>
|
||
<a href="design.htm">Library Design</a><br>
|
||
<a href="faq.htm">FAQ</a><br>
|
||
<a href="portability_guide.htm">Portability Guide</a><br>
|
||
<a href="path.htm"><b><i>path.hpp</i></b> documentation</a><br>
|
||
<a href="operations.htm"><b><i>operations.hpp</i></b> documentation</a><br>
|
||
<a href="fstream.htm"><b><i>fstream.hpp</i></b> documentation</a><br>
|
||
<a href="exception.htm"><b><i>exception.hpp</i></b> documentation</a><br>
|
||
<a href="do-list.htm">Do-list</a></td>
|
||
</tr>
|
||
</table>
|
||
<h2><a name="Introduction">Introduction</a></h2>
|
||
<p>The Boost Filesystem Library provides portable facilities to query and
|
||
manipulate paths, files, and directories.</p>
|
||
|
||
<p>The motivation for the library is the need to be able to perform portable script-like operations from within C++ programs. The intent is not to
|
||
compete with Python, Perl, or shell languages, but rather to provide portable filesystem
|
||
operations when C++ is already the language of choice. The <a href="design.htm">
|
||
design</a> encourages, but does not require, safe and portable filesystem usage.</p>
|
||
|
||
<p>Filesystem Library components are supplied by several headers, all in
|
||
directory boost/filesystem:</p>
|
||
|
||
<ul>
|
||
<li>Header <i>path.hpp</i> provides class <i>path, </i>a portable mechanism for representing
|
||
<a href="#path">paths</a> in C++ programs. Validity checking
|
||
functions are also provided. See <a href="path.htm">path.hpp documentation</a>.<br>
|
||
</li>
|
||
<li>Header <i>operations.hpp</i> provides functions operating on files and directories,
|
||
and includes class <i>directory_iterator</i>. See <a href="operations.htm">
|
||
operations.hpp documentation</a>.<br>
|
||
</li>
|
||
<li>Header <i>fstream.hpp</i> provides the same components as the C++ Standard
|
||
Library's <i>fstream</i> header, except
|
||
that files are identified by <i>path</i> objects rather that <i>char *</i>'s.
|
||
See <a href="fstream.htm">fstream.hpp documentation</a>.<br>
|
||
</li>
|
||
<li>Header <i>exception.hpp</i> provides class <i>filesystem_error</i>. See
|
||
<a href="exception.htm">exception.hpp documentation</a>.<br>
|
||
</li>
|
||
<li>Experimental header <i>
|
||
<a href="../../../boost/filesystem/recursive_directory_iterator.hpp">
|
||
recursive_directory_iterator.hpp</a></i> provides an undocumented directory
|
||
iterator which recurses into any sub-directories encountered. It will be
|
||
incorporated into the Filesystem Library if user feedback is favorable.</li>
|
||
</ul>
|
||
<h2>Two-minute <a name="tutorial">tutorial</a></h2>
|
||
<p>First some preliminaries:</p>
|
||
<blockquote>
|
||
<pre>#include "boost/filesystem/operations.hpp" // includes boost/filesystem/path.hpp
|
||
#include "boost/filesystem/fstream.hpp" // ditto
|
||
#include <iostream> // for cout
|
||
namespace fs = boost::filesystem;</pre>
|
||
</blockquote>
|
||
<p>A <a href="path.htm#synopsis">class <i>path</i></a> object can be created:</p>
|
||
<blockquote>
|
||
<pre>fs::path my_path( "some_dir/file.txt" );</pre>
|
||
</blockquote>
|
||
<p>The string passed to the <i>path</i> constructor is in a
|
||
<a href="path.htm#Grammar">portable generic path format</a>. Access functions
|
||
make <i>my_path</i> contents available in an operating system dependent format,
|
||
such as <code>"some_dir:file.txt"</code>, <code>"[some_dir]file.txt"</code>,
|
||
<code>"some_dir/file.txt"</code>, or whatever is appropriate for the
|
||
operating system.</p>
|
||
<p>Class <i>path</i> has conversion constructors from <i>const char*</i> and <i>
|
||
const std:: string&</i>, so that even though the Filesystem Library functions in
|
||
the following code snippet take <i>const path&</i> arguments, the user can just
|
||
code C-style strings:</p>
|
||
<blockquote>
|
||
<pre>fs::remove_all( "foobar" );
|
||
fs::create_directory( "foobar" );
|
||
fs::ofstream file( "foobar/cheeze" );
|
||
file << "tastes good!\n";
|
||
file.close();
|
||
if ( !fs::exists( "foobar/cheeze" ) )
|
||
std::cout << "Something is rotten in foobar\n";</pre>
|
||
</blockquote>
|
||
<p>Additional class path constructors provide for an operating system dependent
|
||
format, useful for with user provided input:</p>
|
||
<blockquote>
|
||
<pre>int main( int argc, char * argv[] ) {
|
||
fs::path arg_path( argv[1], fs::system_specific );</pre>
|
||
</blockquote>
|
||
<p>To make class <i>path</i> objects easy to use in expressions, <i>operator<<</i>
|
||
appends paths:</p>
|
||
<blockquote>
|
||
<pre>fs::ifstream file1( arg_path << "foo/bar" );
|
||
fs::ifstream file2( arg_path << "foo" << "bar" );</pre>
|
||
</blockquote>
|
||
<p>Note that expressions <i>arg_path << "foo/bar"</i> and <i>arg_path << "foo"
|
||
<< "bar"</i> yield equivalent results.</p>
|
||
<p><a href="operations.htm#Class directory_iterator">Class <i>directory_iterator</i></a>
|
||
is an important component of the library. It provides input iterators over the
|
||
contents of a directory, with the value type being class <i>path</i>.</p>
|
||
<p>The following function, given a directory path and a file name, recursively
|
||
searches the directory and its sub-directories for the file name, returning a
|
||
bool, and if successful, the path to the file that was found. The code
|
||
below is extracted from a real program, slightly modified for clarity:</p>
|
||
<blockquote>
|
||
<pre>bool find_file( const fs::path & dir_path, // in this directory,
|
||
const std::string & file_name, // search for this name,
|
||
fs::path & path_found ) // placing path here if found
|
||
{
|
||
if ( !fs::exists( dir_path ) ) return false;
|
||
fs::directory_iterator end_itr; // default construction yields past-the-end
|
||
for ( fs::directory_iterator itr( dir_path );
|
||
itr != end_itr;
|
||
++itr )
|
||
{
|
||
if ( fs::is_directory( *itr ) )
|
||
{
|
||
if ( find_file( *itr, file_name, path_found ) ) return true;
|
||
}
|
||
else if ( itr->leaf() == file_name ) // see below
|
||
{
|
||
path_found = *itr;
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}</pre>
|
||
</blockquote>
|
||
<p>The expression <i>itr->leaf() == file_name</i>, in the line commented <i>//
|
||
see below</i>, calls the <i>leaf()</i> function on the <i>path</i> object
|
||
returned by the iterator. <i>leaf()</i> returns a string which is a copy of the
|
||
last (closest to the leaf, farthest from the root) file or directory name in the
|
||
<i>path</i> object.</p>
|
||
<p>Notice that <i>find_file()</i> does not do explicit error checking, such as
|
||
verifying that the <i>dir_path</i> argument really represents a directory. All
|
||
Filesystem Library functions throw <a href="exception.htm">filesystem_error</a>
|
||
exceptions if they do not complete successfully, so there is enough implicit
|
||
error checking that this application doesn't need to include additional error
|
||
checking code.</p>
|
||
<p>The tutorial is now over; hopefully you now are ready to write simple,
|
||
script-like, programs using the Filesystem Library!</p>
|
||
<h2><a name="Examples">Examples</a></h2>
|
||
<p>Until a custom-made example is available, see
|
||
<a href="../example/compiler_status.cpp">compiler_status.cpp</a>, an actual
|
||
program which uses the library.</p>
|
||
<p>Test programs are also sometimes useful in understanding a library, as they
|
||
illustrate what the developer expected to work and not work. See:</p>
|
||
<ul>
|
||
<li><a href="../test/path_test.cpp">path_test.cpp</a></li>
|
||
<li><a href="../test/operations_test.cpp">operations_test.cpp</a></li>
|
||
<li><a href="../test/fstream_test.cpp">fstream_test.cpp</a></li>
|
||
</ul>
|
||
<h2><a name="Definitions">Definitions</a></h2>
|
||
<p><b><a name="directory">directory</a> </b>- A container provided by the operating system,
|
||
containing the names of files, other directories, or both. Directories are identified
|
||
by <a href="#directory path">directory path</a>.</p>
|
||
<p><b><a name="directory tree">directory tree</a></b> - A directory and file
|
||
hierarchy viewed as an acyclic graph.</p>
|
||
<p><b><a name="path">path</a> </b>- A possibly empty sequence of names. Each
|
||
element in the sequence, except the last, names a <a href="#directory">directory</a>
|
||
which contains the
|
||
next element. The last element may name either a directory or file. The first
|
||
element is closest to the root of the directory tree, the last element is
|
||
farthest from the root.</p>
|
||
<p>It is traditional to represent a path as a string, where each element in the
|
||
path is represented by a <a href="#name">name</a>, and some operating system
|
||
defined syntax distinguishes between the name elements. Other representations of
|
||
a path are possible, such as each name being an element in a <code>std::vector<std::string></code>.</p>
|
||
<p><b><a name="file path">file path</a></b> - A <a href="#path">path</a> whose
|
||
last element is a file.</p>
|
||
<p><b><a name="directory path">directory path</a></b> - A <a href="#path">path</a>
|
||
whose last element is a directory.</p>
|
||
<p><b><a name="name">name</a></b> - A file or directory name, without any
|
||
<a href="#directory path">directory path</a> information to indicate the file or
|
||
directory's actual location within a directory tree. For some
|
||
operating systems, files and directories may have more than one valid name, such
|
||
as a short-form name and a long-form name.</p>
|
||
<h2><a name="Requirements">Requirements</a></h2>
|
||
<p>Unless otherwise specified, all Filesystem Library functions are required to
|
||
throw a <i><a href="exception.htm">filesystem_error</a></i> exception if the
|
||
implementation cannot successfully complete operations required to meet the
|
||
function's specifications. Such exceptions are in addition to any exceptions
|
||
specified in the function's "Throws" paragraph.</p>
|
||
<p>Filesystem Library functions are permitted to call C++ Standard Library
|
||
functions, so <i>std::bad_alloc</i> exceptions may also be thrown, unless
|
||
otherwise specified.</p>
|
||
<p>There is no rollback guarantee; a Filesystem Library function which throws an
|
||
exception may leave the external file system in an altered state.</p>
|
||
<h2><a name="Race-condition">Race-condition</a> d<a name="Dangers">anger</a></h2>
|
||
<p>The state of files and directories is often
|
||
globally shared, and thus may be changed unexpectedly by other threads,
|
||
processes, or even other computers which have access to the filesystem. As an
|
||
example of the difficulties this can cause, consider that the following asserts
|
||
may fail:</p>
|
||
<blockquote>
|
||
<p><code>assert( exists( "foo" ) == exists( "foo" ) ); //
|
||
(1)<br>
|
||
<br>
|
||
remove_all( "foo" );<br>
|
||
assert( !exists( "foo" ) ); // (2)<br>
|
||
<br>
|
||
assert( is_directory( "foo" ) == is_directory( "foo" ) ); //
|
||
(3)</code></p>
|
||
</blockquote>
|
||
<p>(1) will fail if a non-existent "foo" comes into existence, or an
|
||
existent "foo" is removed, between the first and second call to <i>exists()</i>.
|
||
This could happen if, during the execution of the example code, another thread,
|
||
process, or computer is also performing operations in the same directory.</p>
|
||
<p>(2) will fail if between the call to <i>remove_all()</i> and the call to
|
||
<i>exists()</i> a new file or directory named "foo" is created by another
|
||
thread, process, or computer.</p>
|
||
<p>(3) will fail if another thread, process, or computer removes an
|
||
existing file "foo" and then creates a directory named "foo", between the
|
||
example code's two calls to <i>is_directory()</i>.</p>
|
||
<p>A program which needs to be robust when operating on potentially-shared file
|
||
or directory resources should be prepared for <i>filesystem_error</i> exceptions
|
||
to be thrown from any filesystem function except those explicitly specified as
|
||
not throwing exceptions.</p>
|
||
<h2><a name="Implementation">Implementation</a></h2>
|
||
<p>The current implementation (September, 2002) supports operating systems that have
|
||
either the POSIX or Windows API's available.</p>
|
||
<p>The following tests are provided:</p>
|
||
<ul>
|
||
<li><a href="../test/path_test.cpp">path_test.cpp</a></li>
|
||
<li><a href="../test/operations_test.cpp">operations_test.cpp</a></li>
|
||
<li><a href="../test/fstream_test.cpp">fstream_test.cpp</a></li>
|
||
</ul>
|
||
<p>As of September, 2002, these tests succeed for the following compilers on Windows:</p>
|
||
<ul>
|
||
<li>Borland 5.5.1</li>
|
||
<li>GCC 3.1 (using POSIX implementation, but excluding wide-character fstream tests)</li>
|
||
<li>Intel 6.0</li>
|
||
<li>Metrowerks 8.2</li>
|
||
<li>Microsoft 7.0</li>
|
||
<li>Microsoft 6.0 except fstream_test failed.</li>
|
||
</ul>
|
||
<p>As of September, 2002, some limited use has been successful on Linux using
|
||
GCC and IBM/AIX using Visual Age C++.</p>
|
||
<h2><a name="Acknowledgements">Acknowledgements</a></h2>
|
||
<p>The Filesystem Library was designed and implemented by Beman Dawes, except
|
||
for the <i>directory_iterator</i> and <i>filesystem_error</i> classes which were
|
||
based on prior work from Dietmar K<>hl, as modified by Jan Langer.</p>
|
||
|
||
<p>Key <a href="design.htm#Requirements">design requirements</a> and
|
||
<a href="design.htm#Realities">design realities</a> were developed during extensive discussions on the Boost mailing list,
|
||
followed by comments on the actual implementation. Participants included
|
||
(in more-or-less chronological order) Beman Dawes, Jan Langer, Darin Adler, Michiel
|
||
Salters, Jani Kajala, Jason Stewart, Carl Daniel, David Abrahams, Bill Kempf,
|
||
Jonathan Caves, George Heintzelman, Ken Hagen, Eric Jensen, Joel de Guzman, Jim
|
||
Hyslop, John Maddock, Matt Austern, Peter Dimov, Davlet Panech, Dylan Nicholson, Tom Harris,
|
||
Giovanni Bajo, Baptiste Lepilleur, Thomas Witt, Keith Burton, Mattias Flodin,
|
||
Daniel Frey, Vladimir Prus, Toon Knapen.</p>
|
||
|
||
<p>Specific improvements for a preliminary design document came from Dan Nuffer and Jeff
|
||
Garland.</p>
|
||
|
||
<p>A lengthy discussion on the C++ committee's library reflector illuminated the "illusion
|
||
of portability" problem, particularly in postings by JP Plauger and Pete Becker.</p>
|
||
|
||
<hr>
|
||
<p><EFBFBD> Copyright Beman Dawes, 2002</p>
|
||
<p>Revised
|
||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->13 September, 2002<!--webbot bot="Timestamp" endspan i-checksum="39336" --></p>
|
||
|
||
</body>
|
||
|
||
</html> |