1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
|
<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 operations.hpp Header</title>
</head>
<body bgcolor="#FFFFFF">
<h1>
<img border="0" src="../../../boost.png" align="center" width="277" height="86"><a href="../../../boost/filesystem/operations.hpp">boost/filesystem/operations.hpp</a></h1>
<p><a href="#Introduction">Introduction</a><br>
<a href="#Synopsis">Header synopsis</a><br>
<a href="#directory_iterator">Class directory_iterator</a><br>
<a href="#constructors">Constructors</a><br>
<a href="#Other_functions">Other_functions</a><br>
<a href="#Non-member_functions">Operations functions</a><br>
<a href="#exists">exists</a><br>
<a href="#symbolic_link_exists">symbolic_link_exists</a><br>
<a href="#is_directory">is_directory</a><br>
<a href="#is_empty">is_empty</a><br>
<a href="#equivalent">equivalent</a><br>
<a href="#file_size">file_size</a><br>
<a href="#last_write_time">last_write_time</a><br>
<a href="#create_directory">create_directory</a><br>
<a href="#remove">remove</a><br>
<a href="#remove_all">remove_all</a><br>
<a href="#rename">rename</a><br>
<a href="#copy_file">copy_file</a><br>
<a href="#initial_path">initial_path</a><br>
<a href="#complete">complete</a><br>
<a href="#system_complete">system_complete</a></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>The <a href="../../../boost/filesystem/operations.hpp">
boost/filesystem/operations.hpp</a> header provides operations on files and
directories.</p>
<p>These operations traffic in paths; see <a href="path.htm">
boost/filesystem/path.hpp documentation</a>.</p>
<p>For file I/O streams, see <a href="fstream.htm">boost/filesystem/fstream.hpp
documentation</a>.</p>
<p>The Filesystem Library's <a href="index.htm#Common_Specifications">Common
Specifications</a> apply to all member and non-member functions supplied by this
header. </p>
<h2>Header <a href="../../../boost/filesystem/operations.hpp">boost/filesystem/operations.hpp</a>
<a name="Synopsis">synopsis</a></h2>
<pre>namespace boost
{
namespace filesystem
{
class <a href="#directory_iterator">directory_iterator</a>
{
public:
typedef <a href="path.htm">path</a> value_type;
typedef std::ptrdiff_t difference_type;
typedef const path * pointer;
typedef const path & reference;
typedef std::input_iterator_tag iterator_category;
<a href="#constructors">directory_iterator</a>();
explicit <a href="#constructors">directory_iterator</a>( const path & directory_ph );
// <a href="#Other_functions">Other_functions</a>
// ...
};
bool <a href="#exists">exists</a>( const path & ph );
bool <a href="#symbolic_link_exists">symbolic_link_exists</a>( const path & ph );
bool <a href="#is_directory">is_directory</a>( const path & ph );
bool <a href="#is_empty">is_empty</a>( const path & ph );
bool <a href="#equivalent">equivalent</a>( const path & ph1, const path & ph2 );
boost::intmax_t <a href="#file_size">file_size</a>( const path & ph );
std::time_t <a href="#last_write_time">last_write_time</a>( const path & ph );
void <a href="#last_write_time">last_write_time</a>( const path & ph, std::time_t new_time );
bool <a href="#create_directory">create_directory</a>( const path & directory_ph );
bool <a href="#remove">remove</a>( const path & ph );
unsigned long <a href="#remove_all">remove_all</a>( const path & ph );
void <a href="#rename">rename</a>( const path & from_path,
const path & to_path );
void <a href="#copy_file">copy_file</a>( const path & source_file,
const path & target_file );
const path & <a href="#initial_path">initial_path</a>();
path <a href="#current_path">current_path</a>();
path <a href="#complete">complete</a>( const path & ph,
const path & base = initial_path() );
path <a href="#system_complete">system_complete</a>( const path & ph );
} // namespace filesystem
} // namespace boost
</pre>
<h2><a name="directory_iterator">Class directory_iterator</a></h2>
<p>Class <i>directory_iterator</i> provides a C++ standard conforming input
iterator which accesses the contents of a <a href="index.htm#directory">
directory</a>. </p>
<p>The value type is <i><a href="path.htm">boost::filesystem::path</a></i>, so
dereferencing a <i>directory_iterator</i> yields a <a href="index.htm#path">
path</a> to a file or sub-directory contained within the directory represented by
the directory-path argument supplied at construction. The path returned by
dereferencing a <i>directory_iterator</i> is composed by appending the name of
the directory entry to the directory path supplied at construction.</p>
<p>The order of the path entries returned by dereferencing successive increments
of a <i>directory_iterator</i> is unspecified. Thus depending on the ordering
provided by a particular implementation will result in non-portable code.</p>
<p>A path returned by dereferencing a <i>directory_iterator</i> 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 <i>directory_iterator</i> will never be <code>".."</code>
or <code>"."</code>.</p>
<p><b>Note:</b> 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.</p>
<p><b><a name="symbolic-link-warning">Warning</a>:</b> Programs performing
directory iteration may wish to test, via <a href="#exists">exists()</a>, if the
path returned by dereferencing an iterator actually exists. It could be a
<a href="index.htm#symbolic-link">symbolic link</a> to a non-existent file or
directory. Programs recursively walking directory trees for purposes of removing
and renaming entries may wish to avoid following symbolic links, which can be
detected with <a href="#symbolic_link_exists">symbolic_link_exists()</a>.</p>
<p><b>Warning:</b> If a file or sub-directory is removed from or added to a
directory after the construction of a <i>directory_iterator</i> for the
directory, it is unspecified whether or not subsequent incrementing of the
iterator will ever result in an iterator whose value is the removed or added
directory entry.</p>
<h3><a name="constructors">Constructors</a></h3>
<blockquote>
<p><code>directory_iterator();</code></p>
<p><b>Effects:</b> Constructs a <i>directory_iterator</i> having the <i>
past-the-end</i> value as described in the C++ standard, section 24.1.</p>
<p><code>explicit directory_iterator( const path & directory_ph );</code></p>
<p><b>Effects:</b> Constructs a <i>directory_iterator</i> with a value
representing the first path in <i>directory_ph</i>, or if <code>
empty(directory_ph)</code>, the <i>past-the-end</i> value.</p>
<p><b>Throws:</b> if <code>!exists( directory_ph )</code></p>
<p><b>Note:</b> To iterate over the current directory, write <code>
directory_iterator(current_path())</code> rather than <code>directory_iterator("")</code>.</p>
</blockquote>
<h3><a name="Other_functions">Other functions</a></h3>
<p>Class <i>directory_iterator</i> also supplies all the other functions
required by the C++ standard clause 24 for input iterators, such as <i>operator==</i>,
<i>operator++</i>, and <i>operator*</i>.</p>
<h2><a name="Non-member_functions">Non-member functions</a></h2>
<p>
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:</p>
<ul>
<li>Traffic in <i><a href="path.htm">paths</a></i> rather than <code>char*</code>'s, for much
enhanced portability.</li>
<li>Report errors by throwing exceptions, for safer and better error handling.</li>
<li>Tighten specifications slightly, for improved portability.</li>
</ul>
<p>
<b>Rationale:</b> Functions which already exist in the C++ Standard Library,
such as <i><a href="#remove">remove()</a></i> and <i><a href="#rename">rename()</a></i>,
retain the same names and general behavior in the Filesystem Library, to
minimize surprises.</p>
<p>
<b><a name="not-precondition-rationale">Rationale</a>:</b> Some errors which might
at first glance appear to be preconditions are not
specified as such, but instead will throw exceptions. This is
because the possibility of <a href="index.htm#Race-condition">race-conditions</a>
makes it unreliable to test for preconditions before calling the function. As a
design practice, preconditions are not specified when it is not reasonable for a
program to test for them before calling the function. </p>
<p><b>Empty path r<a name="empty_rationale">ationale</a>:</b> Some errors,
particularly function arguments of empty paths, are specified both in <i>
Precondition</i> and in <i>Throws</i> paragraphs. A non-empty path is specified
as a precondition because an empty path is almost certainly an error, the error
meets the usual criteria for <i>Preconditions</i> as specified in the C++
Standard clause 17, and user pre-detection of the error does not suffer from the
<a href="#not-precondition-rationale">precondition race</a> problem described
above. The error condition is also specified in the <i>Throws</i> paragraph to
ensure that the error results in well-defined rather than implementation-defined
behavior, and because existing practice for the equivalent operating system
function is usually to treat an empty path as an error. The intended use of the
Filesystem Library in script-like programs makes undefined behavior particularly
unattractive.</p>
<p>
<b>Naming Rationale:</b> See class <i>path</i>
<a href="path.htm#Naming_Rationale">Naming Rationale</a>.</p>
<h3><a name="exists">exists</a></h3>
<blockquote>
<p><code>bool exists( const path & ph );</code></p>
<p><b>Returns:</b> True if the operating system reports the path
represented by <i>ph</i> exists, else false.</p>
<p><b>Note: </b>Even if <code>exists( ph ) == true</code>, 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.</p>
<p><b>Note:</b> <code>exists("")</code> is valid and returns false;</p>
</blockquote>
<h3><a name="symbolic_link_exists">symbolic_link_exists</a></h3>
<blockquote>
<p><code>bool symbolic_link_exists( const path & ph );</code></p>
<p><b>Returns:</b> True if the operating system reports the path represented by
<i>ph</i> is present and is a <a href="index.htm#symbolic-link">symbolic link</a>, else false.</p>
<p><b>Note:</b> See the <a href="#symbolic-link-warning">directory iterator
warning</a> for one use of <code>symbolic_link_exists()</code>.</p>
<p><b>Note:</b> The Microsoft Windows operating system does not currently
support symbolic links, so <code>symbolic_link_exists()</code> always returns
false on that platform. (Short-cut files (.lnk) are a Windows application
feature, not an O/S feature.) Programmers should still test for symbolic links
where applicable in case Windows adds the feature, and also so that programs
will be portable to systems like POSIX, where symbolic links may be present.</p>
<p><b>Rationale:</b> The function does not throw if <i>ph</i> is not present,
and is accordingly named <code>symbolic_link_exists</code> rather than <code>
is_symbolic_link</code>. Non-throwing behavior permits testing for all four
possible conditions:</p>
<ul>
<li><i>ph</i> not present: <code>!exists(ph) && !symbolic_link_exists(ph)</code></li>
<li><i>ph</i> present and is not a symbolic link: <code>exists(ph) && !symbolic_link_exists(ph)</code></li>
<li><i>ph</i> present and is a symbolic link to a non-existent file or
directory: <code>!exists(ph) && symbolic_link_exists(ph)</code></li>
<li><i>ph</i> present and is a symbolic link to an existing file or
directory: <code>exists(ph) && symbolic_link_exists(ph)</code></li>
</ul>
</blockquote>
<h3><a name="is_directory">is_directory</a></h3>
<blockquote>
<p><code>bool is_directory( const path & ph );</code></p>
<p><b>Returns:</b> True if the operating system reports the path represented by
<i>ph</i> is a directory, else false.</p>
<p><b>Throws:</b> if <code>!exists(ph)</code></p>
<p><b>Rationale:</b> Treating <code>!exists(ph)</code> as an exception rather
than just returning false came about because in real code <code>!exists(ph)</code>
has
often been the first indicate of a programming error. A compound function returning <code>
exists(ph) && is_directory(ph)</code> can always be added later.</p>
</blockquote>
<h3><a name="is_empty">is_empty</a></h3>
<blockquote>
<p><code>bool is_empty( const path & ph );</code></p>
<p><b>Returns:</b> True if the operating system reports the path represented by
<i>ph</i> is an empty file or empty directory, else false.</p>
<p><b>Throws:</b> if <code>!exists(ph)</code></p>
<p>This function determines if the file or directory identified by the
contents of <i>ph</i> is empty. To determine if a path string itself is empty,
use the <i><a href="path.htm#empty">path::empty()</a></i> function.</p>
</blockquote>
<h3><a name="equivalent">equivalent</a></h3>
<blockquote>
<pre>bool equivalent( const path & ph1, const path & ph2 );</pre>
<p><b>Returns:</b> <code>false</code> if <code>!exists(ph1) || !exists(ph2)</code>.
Otherwise, returns <code>true</code> if ph1 and ph2 resolve to the same file
or directory, else <code>false</code>. The criteria used to determine sameness
are implementation defined:</p>
<blockquote>
<ul>
<li>POSIX: stat() reports identical st_dev, st_ino, st_size, and st_mtime
values. The POSIX implementation does not protect against
<a href="index.htm#Race-condition">race conditions</a>.<br>
</li>
<li>Windows: GetFileInformationByHandle() reports identical dwVolumeSerialNumber,
nFileIndexHigh, nFileIndexLow, nFileSizeHigh, nFileSizeLow values,
ftLastWriteTime.dwLowDateTime, and ftLastWriteTime.dwHighDateTime.
Note that for identical media (particularly bit-for-bit duplicate CD's,
Floppies, or memory cards) equivalent() will return <code>true</code> even though the
media are physically different. The Windows implementation does protect
against <a href="index.htm#Race-condition">race conditions</a>.</li>
</ul>
</blockquote>
<p><b>Throws:</b> if <code>!exists(ph1) && !exists(ph2)</code></p>
<p><b>Warning:</b> This function may be impossible to implement on some
operating systems; users may wish to avoid use for code which may be ported to
operating systems with limited filesystem support.</p>
</blockquote>
<h3><a name="file_size">file_size</a></h3>
<blockquote>
<p><code>boost::intmax_t file_size( const path & ph );</code></p>
<p><b>Returns:</b> The size of the file in bytes as reported by the operating
system.</p>
<p><b>Throws:</b> if <code>!exists(ph) || is_directory(ph) || </code>the file
size cannot be determined (such as for an input stream).</p>
<p><b>Warming:</b> If a compiler does not support <code>maxint_t</code> large
enough to represent the operating system's maximum file size, or if the
implementation does not know how to query the operating system for large file
sizes, the returned value could be incorrect. This is not a problem with modern
compilers on modern versions of Linux or Windows. Users on other platforms
should build and run the <a href="../example/file_size.cpp">file_size.cpp</a>
sample program against a large file to verify correct operation.</p>
<p><b>Rationale:</b> Directories are excluded because the complexity of finding
the size of a file is typically constant, while finding the size of a directory
is typically linear. It was felt this would be surprising. The function is named
accordingly. Users needing the size of a directory can trivially provide a user
function which iterates over a directory returning a count.</p>
</blockquote>
<h3><a name="last_write_time">last_write_time</a></h3>
<blockquote>
<p><b>Warning:</b> The times associated with files are subject to many
vicissitudes. Each type of filesystem differs slightly in the details and
resolution of how times are recorded. The resolution is as low as one hour on
some filesystems. It is not uncommon for a program to
simultaneously have access to files maintained by FAT, ISO9660, NTFS, and POSIX
filesystems, and so experience different last_write_time behavior for different
files. During program execution, the system clock may be set to a new
value by some other, possibly automatic, process. Another thread or process may
write to a file, causing the last write time to change unexpectedly.</p>
<p><code>std::time_t last_write_time( const path & ph );</code></p>
<p><b>Returns:</b> The time the file was last modified, as reported by the
operating system. If the time cannot be determined, returns (std::time_t)(-1).</p>
<p>To convert the returned value to UTC or local time, use <code>std::gmtime()</code>
or <code>std::localtime()</code> respectively.</p>
<p><b>Throws:</b> if <code>!exists(ph)</code></p>
<p><code>void last_write_time( const path & ph, std::time_t new_time );</code></p>
<p><b>Effects:</b> Asks the operating system to set the last write time to <code>
new_time</code>, or to the current time if <code>new_time==std::time_t()</code>.</p>
<p><b>Throws:</b> if <code>!exists(ph)</code></p>
<p><b>Rationale:</b> <code>last_write_time(ph)==new_time</code> is not specified
as a postcondition because the times may differ somewhat on some operating
systems.</p>
</blockquote>
<h3><a name="create_directory">create_directory</a></h3>
<blockquote>
<p><code>bool create_directory( const path & directory_ph );</code></p>
<p><b>Precondition:</b> <code>!directory_ph.empty()</code></p>
<p><b>Returns:</b> The value of <code>!exists( directory_ph )</code> prior to the
establishment of the postcondition.</p>
<p><b>Postcondition:</b> <code>exists(directory_ph) &&
is_directory(directory_ph)</code></p>
<p><b>Throws: </b>if <code>directory_ph.empty() || (exists(directory_ph) && !is_directory(directory_ph)) || !exists(directory_ph/"..")</code>.
See <a href="#empty_rationale">empty path rationale</a>.</p>
</blockquote>
<h3><a name="remove">remove</a></h3>
<blockquote>
<p><code>bool remove( const path & ph );</code></p>
<p><b>Precondition:</b> <code>!ph.empty()</code></p>
<p><b>Returns:</b> The value of <code>exists( ph )</code> prior to the
establishment of the postcondition. </p>
<p><b>Postcondition:</b> <code>!exists( ph )</code></p>
<p><b>Throws:</b> if<code> ph.empty() || (exists(ph) && is_directory(ph) && !is_empty(ph))</code>.
See <a href="#empty_rationale">empty path rationale</a>.</p>
<p><b>Note:</b> <a href="index.htm#symbolic-link">Symbolic links</a> are
themselves deleted, rather than what they point to being deleted.</p>
<p><b>Rationale:</b> Does not throw when <code>!exists( ph )</code> because not
throwing:</p>
<ul>
<li>Works correctly if <code>ph</code> is a dangling symbolic link. </li>
<li>Is slightly easier-to-use for many common use cases.</li>
<li>Is 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.</li>
</ul>
<p>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.</p>
<p>The initial version of the library threw an exception when the path did not exist; it
was changed to reflect user complaints.</p>
</blockquote>
<h3><a name="remove_all">remove_all</a></h3>
<blockquote>
<p><code>unsigned long remove_all( const path & ph );</code></p>
<p><b>Precondition:</b> <code>!ph.empty()</code></p>
<p><b>Postcondition:</b> <code>!exists( ph ) && !symbolic_link_exists( ph )</code></p>
<p><b>Returns:</b> The number of files and directories removed.</p>
<p><b>Throws:</b> if<code> ph.empty()</code>. See <a href="#empty_rationale">
empty path rationale</a>.</p>
<p><b>Note:</b> <a href="index.htm#symbolic-link">Symbolic links</a> are
themselves deleted, rather than what they point to being deleted.</p>
</blockquote>
<h3><a name="rename">rename</a></h3>
<blockquote>
<p><code>void rename( const path & source, const path & target
);</code></p>
<p><b>Precondition:</b> <code>!source.empty() && !target.empty()</code></p>
<p><b>Effects:</b> Changes the name of file or directory <i>source</i>
to <i>target</i>. Specifically:</p>
<table border="1" cellpadding="5">
<tr>
<td><b>Source</b></td>
<td><b>Target</b></td>
<td><b>Result is "as if" these actions occur</b></td>
</tr>
<tr>
<td>!exists()</td>
<td> </td>
<td>Throw <a href="exception.htm">filesystem_error</a>. Note that !exists()
covers the source.empty() case. [case 1] </td>
</tr>
<tr>
<td> </td>
<td>target.empty()</td>
<td>Throw <a href="exception.htm">filesystem_error</a>. See
<a href="#empty_rationale">create_directory() rationale</a>. [case 2] </td>
</tr>
<tr>
<td> </td>
<td>exists()</td>
<td>Throw <a href="exception.htm">filesystem_error</a>. [case 3] </td>
</tr>
<tr>
<td>!is_directory()</td>
<td> </td>
<td>If !exists( target / ".." ) throw <a href="exception.htm">
filesystem_error</a>. [case 4A] <br>
The source.leaf() name is changed to
target.leaf(). [case 4B] <br>
If source / ".." resolves to a different directory than
target / "..", the renamed source file is moved there. [case 4C] </td>
</tr>
<tr>
<td>is_directory()</td>
<td> </td>
<td>If !exists( target / ".." ) throw <a href="exception.htm">
filesystem_error</a>. [case 5A]<br>
The source.leaf() name is changed to
target.leaf(). [case 5B] <br>
If system_complete(source.banch_path()) resolves to a
different directory than system_complete(target.branch_path()), the
renamed source directory is moved there. [case 5C] </td>
</tr>
</table>
<p><b>Postconditions:</b> <code>!exists(source) && exists(target)</code>,
and the <i>source</i> file or directory contents and attributes are otherwise unchanged.</p>
<p><b>Throws:</b> See Effects table above. See <a href="#empty_rationale">empty
path rationale</a>.</p>
<p><b>Rationale:</b> Because <i>rename</i> is logically the same operation as <i>move</i>,
there is no need for a separate <i>move</i> function. The choice of the name is
based on existing practice in the C, C++, and POSIX libraries, and because the
name <i>move</i> implies physical file movement, which does not in fact occur.</p>
<p><b>Note:</b> Some operating systems with
<a href="index.htm#multi-root_filesystem">multiple roots</a> do not allow <i>rename</i>
operations between roots, and such an attempted <i>rename</i> with throw a <i>
<a href="exception.htm">filesystem_error</a></i> exception.. Implementations should not take heroic efforts, such
as switching to a copy mode, to make an otherwise failing <i>rename </i>succeed
across roots.</p>
<p><b>Note:</b> <a href="index.htm#symbolic-link">Symbolic links</a> are
themselves renamed, rather than what they point to being renamed.</p>
</blockquote>
<h3><a name="copy_file">copy_file</a></h3>
<blockquote>
<p><code>void copy_file( const path & source_file, const path &
target_file );</code></p>
<p><b>Precondition:</b> <code>!source.empty() && !target.empty()</code></p>
<p><b>Effects:</b> Copies the file represented by <i>source_file</i> to <i>
target_file</i>.</p>
<p><b>Throws:</b> if <code>!exists(source_file) || is_directory(source_file)
|| exists(target_file) || target_file.empty() || !exists(to_file_path/".."))</code>.
See <a href="#empty_rationale">empty path rationale</a>.</p>
<p><b>Note:</b> File attributes are also copied. Specifically, POSIX <i>
stat::st_mode</i>, and Windows <i>BY_HANDLE_FILE_INFORMATION::dwFileAttributes</i>. </p>
</blockquote>
<h3><a name="initial_path">initial_path</a></h3>
<blockquote>
<p><code>const path & initial_path();</code></p>
<p><b>Effects:</b> The first time called, stores the path returned by
<a href="#current_path">current_path()</a>.</p>
<p>The preferred implementation would be to call <i>initial_path()</i> during program
initialization, before the call to <i>main()</i>. This is, however, not possible
with changing the C++ runtime library.</p>
<p><b>Returns:</b> A reference to the stored path.</p>
<p><b>Rationale:</b> The semantics, in effect, turn a dangerous 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.</p>
<p><b>Note:</b> It is good practice for a program dependent on <i>
initial_path()</i> to call it immediately upon entering<i> main()</i>. That
protects against another function altering the current working
directory (using a native platform function) before the first call to <i>
initial_path()</i>.</p>
</blockquote>
<h3><a name="current_path">current_path</a></h3>
<blockquote>
<pre>path current_path();</pre>
<p><b>Returns:</b> The current path as maintained by the operating system.</p>
<p><b>Postcondition:</b> <code>current_path().is_complete()</code></p>
<p><b>Note:</b> The equivalent POSIX function is <i>getcwd()</i>. The
equivalent Windows function is <i>GetCurrentDirectoryA()</i>.</p>
<p><b>Warning:</b> The current path maintained by the operating system is
in-effect a dangerous global variable. It may be changed unexpectedly by a
third-party or system library function, or by another thread. For a safer
alternative, see <a href="#initial_path">initial_path()</a>.</p>
<p><b>Rationale:</b> Although dangerous, the function is useful in dealing
with other libraries. The <i>current_path()</i> name was chosen to emphasize
that the function returns a complete path, not just a single directory name.</p>
</blockquote>
<h3><a name="complete">complete</a></h3>
<blockquote>
<p><code>path complete( const path & ph, const path & base = initial_path() );</code></p>
<p><b>Precondition:</b> <code>!ph.empty() && base.is_complete() && (ph.is_complete() || !ph.has_root_name())</code></p>
<p><b>Effects:</b> Composes a complete path from <code>ph</code> and <code>base</code>,
using the following rules:</p>
<p>For single-root operating systems (POSIX-like systems, for example), if <code>ph.empty()</code>
or <code>ph.is_complete()</code>, the composed path is <code>ph</code>,
otherwise the composed path is <code>base/ph</code>.</p>
<p>For <a href="index.htm#multi-root_filesystem">multi-root</a> operating systems (Windows, Classic Mac, many others), the rules are
give by this table:</p>
<table border="1" cellpadding="5">
<tr>
<td align="center"> </td>
<td align="center"><code>ph.has_root_directory()</code></td>
<td align="center"><code>!ph.has_root_directory()</code></td>
</tr>
<tr>
<td align="center"><code>ph.has_root_name()</code></td>
<td align="center"><code>ph</code></td>
<td align="center"><code>(precondition failure)</code></td>
</tr>
<tr>
<td align="center"><code>!ph.has_root_name()</code></td>
<td align="center"><code>base.root_name()<br>
/ ph</code></td>
<td align="center"><code>base / ph</code></td>
</tr>
</table>
<p><b>Returns:</b> The composed path.</p>
<p><b>Postcondition:</b> For the returned path, <code>p,</code> <code>p.is_complete()</code>
is true.</p>
<p><b>Throws:</b> On precondition failure. See <a href="#empty_rationale">empty
path rationale</a>.</p>
<p><b><a name="complete_note">Note</a>:</b> When portable behavior is required,
use <i>complete()</i>. When operating system dependent behavior is required, use
<i>system_complete()</i>.</p>
<p>Portable behavior is preferred when dealing with paths created internally
within a program, particularly where the program should exhibit the same
behavior on all operating systems.</p>
<p>Operating system dependent behavior is preferred when dealing with paths
supplied by user input, reported to program users, or which should result in
program behavior familiar to and expected by program users. The
<a href="../example/simple_ls.cpp">simple_ls.cpp</a> program, for example,
operates on a path supplied in the native operating system format, so uses
<i>system_complete()</i> to ensure that the path behaves as expected for the
particular operating system.</p>
<p><b>Rationale:</b> The <code>!ph.has_root_name()</code> portion of the
precondition disallows the error condition of <code>ph.root_name()</code>
being not equivalent to <code>base.root_name()</code>. The restriction is
broader that would appear necessary, in that is also prohibits the case where
they are equivalent. There is, however, no portable way to express the
root_name() equivalence requirement.</p>
</blockquote>
<h3><a name="system_complete">system_complete</a></h3>
<blockquote>
<p><code>path system_complete( const path & ph );</code></p>
<p><b>Precondition:</b> <code>!ph.empty()</code></p>
<p><b>Effects:</b> Composes a complete path from <code>ph</code>, using the same
rules used by the operating system to resolve a path passed as the filename
argument to standard library open functions.</p>
<p>For POSIX-like systems, system_complete( ph ) has the same semantics as <code>
complete( ph, current_path() )</code>.</p>
<p><a name="windows_effects">For Widows</a>, system_complete( ph ) has the same
semantics as <code>complete( ph, current_path() )</code> if ph.is_complete() ||
!ph.has_root_name() or ph and base have the same root_name().
Otherwise it acts like <code>complete( ph, kinky )</code>, where <code>kinky</code>
is the current directory for the <code>ph.root_name()</code> drive. This
will be the current directory of that drive the last time it was set, and thus
may well be <b>residue left over from some prior program</b> run by the command
processor! Although these semantics are often useful, they are also very
error-prone, and certainly deserve to be called "kinky".</p>
<p><b>Returns:</b> The composed path.</p>
<p><b>Postcondition:</b> For the returned path, <code>p,</code> <code>p.is_complete()</code>
is true.</p>
<p><b>Throws:</b> If <code>ph.empty()</code>. See <a href="#empty_rationale">
empty path rationale</a>.</p>
<p><b>Note:</b> See <a href="#complete_note"><i>complete()</i> note</a> for
usage suggestions.</p>
<p><b>Warning:</b> This function relies on a global variable (current_path()),
and so tends to be more error-prone than the similar function
<a href="#complete">complete()</a>. This function is doubly dangerous on
Windows, where under cross-drive conditions it may be relying on a directory set
by a prior program run by the command processor.</p>
</blockquote>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->02 August, 2005<!--webbot bot="Timestamp" endspan i-checksum="34600" --></p>
<p> Copyright Beman Dawes, 2002</p>
<p> Use, modification, and distribution are subject to the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>
|