1<html> 2 3<head> 4<meta http-equiv="Content-Language" content="en-us"> 5<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> 6<meta name="ProgId" content="FrontPage.Editor.Document"> 7<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 8<title>Filesystem Tutorial</title> 9<link href="styles.css" rel="stylesheet"> 10</head> 11 12<body> 13 14<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> 15 <tr> 16 <td width="277"> 17<a href="../../../index.htm"> 18<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="300" height="86" border="0"></a></td> 19 <td align="middle"> 20 <font size="7">Filesystem Tutorial</font> 21 </td> 22 </tr> 23</table> 24 25<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" 26 bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> 27 <tr> 28 <td><a href="index.htm">Home</a> 29 <a href="tutorial.html">Tutorial</a> 30 <a href="reference.html">Reference</a> 31 <a href="faq.htm">FAQ</a> 32 <a href="release_history.html">Releases</a> 33 <a href="portability_guide.htm">Portability</a> 34 <a href="v3.html">V3 Intro</a> 35 <a href="v3_design.html">V3 Design</a> 36 <a href="deprecated.html">Deprecated</a> 37 <a href="issue_reporting.html">Bug Reports </a> 38 </td> 39</table> 40 41<p> 42 <a href="#Introduction">Introduction</a><br> 43 <a href="#Preliminaries">Preliminaries</a><br> 44 <a href="#Reporting-size">Reporting the size of a file - (tut1.cpp)</a><br> 45 <a href="#Using-status-queries">Using status queries to determine file existence and type - (tut2.cpp)</a><br> 46 <a href="#Directory-iteration">Directory iteration plus catching 47 exceptions - (tut3.cpp)</a><br> 48 <a href="#Using-path-decomposition">Using path decomposition, plus sorting results - (tut4.cpp)</a><br> 49 <a href="#Class-path-Constructors">Class path: Constructors, including 50 Unicode - (tut5.cpp)</a><br> 51 <a href="#Class-path-formats">Class path: Generic format vs. Native format</a><br> 52 <a href="#Class path-iterators-etc">Class path: Iterators, observers, composition, decomposition, and query - (path_info.cpp)</a><br> 53 <a href="#Error-reporting">Error reporting</a><br> 54</p> 55<h2><a name="Introduction">Introduction</a></h2> 56 57<p>This tutorial develops a little command line program to list information 58about files and directories - essentially a much simplified version of the POSIX <code>ls</code> or Windows <code>dir</code> 59commands. We'll start with the simplest possible version and progress to more 60complex functionality. Along the way we'll digress to cover topics you'll need 61to know about to understand Boost.Filesystem.</p> 62 63<p>Source code for each of the tutorial programs is available, and you 64are encouraged to compile, test, and experiment with it. To conserve space, we won't 65always show boilerplate code here, but the provided source is complete and 66ready to build.</p> 67 68<h2><a name="Preliminaries">Preliminaries</a></h2> 69 70<p>Install the Boost distribution if you haven't already done so. See the 71<a href="http://www.boost.org/more/getting_started/index.html">Boost Getting 72Started</a> docs.</p> 73 74<p>This tutorial assumes you are going to compile and test the examples using 75the provided scripts. That's highly recommended.</p> 76 77<blockquote> 78 79<p><b>If you are planning to compile and test the examples but not use the 80scripts, make sure your build setup knows where to 81locate or build the Boost library binaries.</b></p> 82 83</blockquote> 84<p>Fire up your command line interpreter, and type the following commands:</p> 85 86 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 87 <tr> 88 <td align="center"><i><b>Ubuntu Linux </b></i></td> 89 </tr> 90 <tr> 91 <td> 92 <pre>$ cd <i><b>boost-root</b></i>/libs/filesystem/example/test 93 94$ ./setup.sh 95Copying example programs... 96 97$ ./build.sh 98Compiling example programs... 99 100$ ./tut1 101Usage: tut1 path</pre> 102 </td> 103 </tr> 104 </table> 105 106 107 108 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 109 <tr> 110 <td align="center"><i><b>Microsoft Windows</b></i></td> 111 </tr> 112 <tr> 113 <td> 114 <pre>>cd <i><b>boost-root</b></i>\libs\filesystem\example\test 115 116>setup 117Copying example programs... 118 119>build 120Compiling example programs... 121 122>tut1 123Usage: tut1 path</pre> 124 </td> 125 </tr> 126 </table> 127 128<p>If the <code>tut1</code> command outputs "<code>Usage: tut1 path</code>", all 129is well. A set of tutorial example programs has been copied (by <code>setup</code>) to 130<i><b><code>boost-root</code></b></i><code>/libs/filesystem/example/test</code> 131and then built. You are encouraged to modify and experiment with them as the 132tutorial progresses. Just invoke the <code>build</code> script again to rebuild, 133or invoke <code>b2</code> directly.</p> 134 135<p>If something didn't work right, here are some troubleshooting suggestions:</p> 136 137 <ul> 138 <li>If the <code>b2</code> program executable isn't being found, check your path environmental variable 139 or see 140 <a href="http://www.boost.org/more/getting_started/windows.html">Boost 141 Getting Started</a>.<br> 142 </li> 143 <li>Look at <code>b2.log</code> to try to spot an indication of the 144 problem.</li> 145 </ul> 146 147<h2><a name="Reporting-size">Reporting the size of a file</a> - (<a href="../example/tut1.cpp">tut1.cpp</a>)</h2> 148 149<p>Let's get started. Our first example program, <a href="../example/tut1.cpp">tut1.cpp</a>, 150reports the size of a file:</p> 151 152<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 153 <tr> 154 <td> 155 <pre><!-- include file "../example/tut1.cpp" -->#include <iostream> 156#include <boost/filesystem.hpp> 157using namespace boost::filesystem; 158 159int main(int argc, char* argv[]) 160{ 161 if (argc < 2) 162 { 163 std::cout << "Usage: tut1 path\n"; 164 return 1; 165 } 166 std::cout << argv[1] << " " << file_size(argv[1]) << '\n'; 167 return 0; 168}<!-- end include file --></pre> 169 </td> 170 </tr> 171</table> 172 173<p>The Boost.Filesystem <code><a href="reference.html#file_size">file_size</a></code> 174function returns a <code>uintmax_t</code> 175containing the size of the file named by the argument. The declaration looks 176like this:</p> 177 178<blockquote> 179 <pre><code>uintmax_t file_size(const path& p);</code> </pre> 180</blockquote> 181<p>For now, all you need to know is that <code>class path</code> has constructors that take 182<code>const char *</code> and other string types. (If you can't wait to 183find out more, skip ahead to the <a href="#Class-path-Constructors">class path</a> section of 184the tutorial.)</p> 185<p>Please take a minute to try out <code>tut1</code> on your system, using a 186file that is known to exist, such as <code>tut1.cpp</code>. Here is what the 187results look like on two different operating systems:</p> 188 189 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 190 <tr> 191 <td align="center"><i><b>Ubuntu Linux </b></i></td> 192 </tr> 193 <tr> 194 <td valign="top"> 195 <pre>$ ./tut1 tut1.cpp 196tut1.cpp 569</pre> 197 <pre>$ ls -l tut1.cpp 198-rw-rw-r-- 1 beman beman 569 Jul 26 12:04 tut1.cpp</pre> 199 </td> 200 </tr> 201 </table> 202 203 204 205 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 206 <tr> 207 <td align="center"><i><b>Microsoft Windows</b></i></td> 208 </tr> 209 <tr> 210 211 <td valign="top"> 212 <pre>>tut1 tut1.cpp 213tut1.cpp 592 214 215>dir tut1.cpp 216... 21707/26/2015 07:20 AM 592 tut1.cpp 218...</pre> 219 </td> 220 </tr> 221 </table> 222 223<p>So far, so good. The reported Linux and Windows sizes are different because 224the Linux tests used <code>"\n"</code> line endings, while the Windows tests 225used <code>"\r\n"</code> line endings. The sizes reported may differ 226from the above if changes have been made to <code>tut1.cpp</code>.</p> 227 <p>Now try again, but give a path that doesn't exist:</p> 228 229 <table border="1" cellpadding="5" cellspacing="0" 230 style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 231 <tr> 232 <td align="center"><i><b>Ubuntu Linux </b></i></td> 233 </tr> 234 <tr> 235 <td valign="top"> 236 <pre>$ ./tut1 foo 237terminate called after throwing an instance of 'boost::filesystem::filesystem_error' 238what(): boost::filesystem::file_size: No such file or directory: "foo" 239Aborted (core dumped)</pre> 240 </td> 241 </tr> 242 </table> 243 244 245 246 <table border="1" cellpadding="5" cellspacing="0" 247 style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 248 <tr> 249 <td align="center"><i><b>Microsoft Windows</b></i></td> 250 </tr> 251 <tr> 252 <td valign="top"> 253 <pre>>tut1 foo</pre> 254 <p><b><i>An exception is thrown;<br> 255 the exact form of the response depends on 256 Windows system options.</i></b></td> 257 </tr> 258 </table> 259 260 <p>What happens? 261 There's no file named <code>foo</code> in the current directory, so by default an 262exception is thrown. See <a href="#Error-reporting">Error reporting</a> to learn 263 about error reporting via error codes rather than exceptions.</p> 264 <p>Try this:</p> 265 266 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 267 <tr> 268 <td align="center"><i><b>Ubuntu Linux </b></i></td> 269 </tr> 270 <tr> 271 <td> 272 <pre>$ ./tut1 . 273terminate called after throwing an instance of 'boost::filesystem::filesystem_error' 274what(): boost::filesystem::file_size: Operation not permitted: "." 275Aborted (core dumped)</pre> 276 </td> 277 </tr> 278 </table> 279 280 281 282 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 283 <tr> 284 <td align="center"><i><b>Microsoft Windows</b></i></td> 285 </tr> 286 <tr> 287 <td valign="top"> 288 <pre>>tut1 .</pre> 289 <p><b><i>An exception is thrown;<br> 290 the exact form of the response depends on Windows system options.</i></b></td> 291 </tr> 292 </table> 293 294 <p>The current directory exists, but <code>file_size()</code> works on regular 295 files, not directories, so again an exception is thrown.</p> 296 297 <p>We'll deal with those situations in <code>tut2.cpp</code>.</p> 298 299<h2><a name="Using-status-queries">Using status queries to determine file existence and type</a> - (<a href="../example/tut2.cpp">tut2.cpp</a>)</h2> 300 301<p>Boost.Filesystem includes status query functions such as <code> 302<a href="reference.html#exists-path">exists</a></code>, 303<code><a href="reference.html#is_directory-path">is_directory</a></code>, and <code> 304<a href="reference.html#is_regular_file-path">is_regular_file</a></code>. These return 305<code>bool</code>'s, and will return <code>true</code> if the condition 306described by their name is met. Otherwise they return <code>false</code>, 307including when any element 308of the path argument can't be found.</p> 309 310<p><a href="../example/tut2.cpp">tut2.cpp</a> uses several of the status query functions to cope with non-existent 311files and with different kinds of files:</p> 312 313<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 314 <tr> 315 <td> 316 <pre><!-- include file "../example/tut2.cpp" -->#include <iostream> 317#include <boost/filesystem.hpp> 318using namespace std; 319using namespace boost::filesystem; 320 321int main(int argc, char* argv[]) 322{ 323 if (argc < 2) 324 { 325 cout << "Usage: tut2 path\n"; 326 return 1; 327 } 328 329 path p(argv[1]); // avoid repeated path construction below 330 331 if (exists(p)) // does path p actually exist? 332 { 333 if (is_regular_file(p)) // is path p a regular file? 334 cout << p << " size is " << file_size(p) << '\n'; 335 336 else if (is_directory(p)) // is path p a directory? 337 cout << p << " is a directory\n"; 338 339 else 340 cout << p << " exists, but is not a regular file or directory\n"; 341 } 342 else 343 cout << p << " does not exist\n"; 344 345 return 0; 346}<!-- end include file --></pre> 347 </td> 348 </tr> 349</table> 350 351<p>Give it a try:</p> 352 353 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 354 <tr> 355 <td align="center"><i><b>Ubuntu Linux </b></i></td> 356 </tr> 357 <tr> 358 <td valign="top"> 359 <pre>$ ./tut2 tut2.cpp 360"tut2.cpp" size is 997 361 362$ ./tut2 foo 363"foo" does not exist 364 365$ ./tut2 . 366"." is a directory</pre> 367 </td> 368 </tr> 369 </table> 370 371 372 373 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 374 <tr> 375 <td align="center"><i><b>Microsoft Windows</b></i></td> 376 </tr> 377 <tr> 378 <td valign="top"> 379 <pre>>tut2 tut2.cpp 380tut2.cpp size is 1039 381 382>tut2 foo 383"foo" does not exist 384 385>tut2 . 386"." is a directory</pre> 387 </td> 388 </tr> 389 </table> 390 391<p>Although tut2 works OK in these tests, the output is less than satisfactory 392for a directory. We'd typically like to see a list of the directory's contents. In <code>tut3.cpp</code> 393we will see how to iterate over directories.</p> 394 395<p>But first, let's try one more test:</p> 396 397 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 398 <tr> 399 <td align="center"><i><b>Ubuntu Linux </b></i></td> 400 </tr> 401 <tr> 402 <td valign="top"> 403 <pre>$ ls /home/jane/foo 404ls: cannot access /home/jane/foo: No such file or directory 405 406$ ./tut2 /home/jane/foo 407terminate called after throwing an instance of 'boost:: 408filesystem::filesystem_error>' 409 what(): boost::filesystem::status: Permission denied: 410 "/home/jane/foo" 411Aborted</pre> 412 </td> 413 </tr> 414 </table> 415 416 417 418 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 419 <tr> 420 <td align="center"><i><b>Microsoft Windows</b></i></td> 421 </tr> 422 <tr> 423 <td valign="top"> 424 <pre>>dir e:\ 425The device is not ready. 426 427>tut2 e:\</pre> 428 <p dir="ltr"><b><i>An exception is thrown;<br> 429 the exact form of the response depends on 430 Windows system options.</i></b></td> 431 </tr> 432 </table> 433 434<p>On the Linux system, the test was being run from an account that did not have 435permission to access <code>/home/jane/foo</code>. On the Windows system, <code> 436e:</code> was a Compact Disc reader/writer that was not ready. End users 437shouldn't have to interpret cryptic exceptions reports, so as we move on to <code>tut3.cpp</code> 438we will increase the robustness of the code, too.</p> 439 440<h2><a name="Directory-iteration">Directory iteration</a> plus catching 441exceptions - (<a href="../example/tut3.cpp">tut3.cpp</a>)</h2> 442 443<p>Boost.Filesystem's <code><a href="reference.html#directory_iterator"> 444directory_iterator</a></code> class is just what we need here. It follows the 445general pattern of the standard library's <code>istream_iterator</code>. Constructed from 446a path, it iterates over the contents of the directory. A default constructed <code>directory_iterator</code> 447acts as the end iterator.</p> 448 449<p>The value type of <code>directory_iterator</code> is <code> 450<a href="reference.html#directory_entry">directory_entry</a></code>. A <code> 451directory_entry</code> object contains <code>path</code> and <code><a href="reference.html#file_status">file_status</a></code> 452information. A <code> 453directory_entry</code> object 454can be used directly, but can also be passed to <code>path</code> arguments in function calls.</p> 455 456<p>The other need is increased robustness in the face of the many kinds of 457errors that can affect file system operations. We could do that at the level of 458each call to a Boost.Filesystem function (see <a href="#Error-reporting">Error 459reporting</a>), but for simplicity <a href="../example/tut3.cpp">tut3.cpp</a> 460uses an overall try/catch block.</p> 461 462<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 463 <tr> 464 <td> 465 <pre><!-- include file "../example/tut3.cpp" -->#include <iostream> 466#include <boost/filesystem.hpp> 467using std::cout; 468using namespace boost::filesystem; 469 470int main(int argc, char* argv[]) 471{ 472 if (argc < 2) 473 { 474 cout << "Usage: tut3 path\n"; 475 return 1; 476 } 477 478 path p (argv[1]); 479 480 try 481 { 482 if (exists(p)) 483 { 484 if (is_regular_file(p)) 485 cout << p << " size is " << file_size(p) << '\n'; 486 487 else if (is_directory(p)) 488 { 489 cout << p << " is a directory containing:\n"; 490 491 for (directory_entry& x : directory_iterator(p)) 492 cout << " " << x.path() << '\n'; 493 } 494 else 495 cout << p << " exists, but is not a regular file or directory\n"; 496 } 497 else 498 cout << p << " does not exist\n"; 499 } 500 501 catch (const filesystem_error& ex) 502 { 503 cout << ex.what() << '\n'; 504 } 505 506 return 0; 507}<!-- end include file --></pre> 508 </td> 509 </tr> 510</table> 511 512<p>Give <code>tut3</code> a try, passing it a path to a directory as a command line argument. 513Here is a run on a checkout of the Boost Git develop branch, followed by a repeat 514of the test cases that caused exceptions on Linux and Windows:</p> 515 516 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 517 <tr> 518 <td align="center"><i><b>Ubuntu Linux </b></i></td> 519 </tr> 520 <tr> 521 <td valign="top"> 522 <pre>$ ./tut3 ~/boost/develop 523 "/home/beman/boost/develop" is a directory containing: 524 "/home/beman/boost/develop/rst.css" 525 "/home/beman/boost/develop/boost" 526 "/home/beman/boost/develop/boost.png" 527 "/home/beman/boost/develop/libs" 528 "/home/beman/boost/develop/doc" 529 "/home/beman/boost/develop/project-config.jam.2" 530 "/home/beman/boost/develop/.gitmodules" 531 "/home/beman/boost/develop/boostcpp.py" 532 "/home/beman/boost/develop/.travis.yml" 533 "/home/beman/boost/develop/.gitattributes" 534 "/home/beman/boost/develop/index.htm" 535 "/home/beman/boost/develop/index.html" 536 "/home/beman/boost/develop/bjam" 537 "/home/beman/boost/develop/project-config.jam.1" 538 "/home/beman/boost/develop/LICENSE_1_0.txt" 539 "/home/beman/boost/develop/.git" 540 "/home/beman/boost/develop/tools" 541 "/home/beman/boost/develop/stage" 542 "/home/beman/boost/develop/boostcpp.jam" 543 "/home/beman/boost/develop/Jamroot" 544 "/home/beman/boost/develop/.gitignore" 545 "/home/beman/boost/develop/INSTALL" 546 "/home/beman/boost/develop/more" 547 "/home/beman/boost/develop/bin.v2" 548 "/home/beman/boost/develop/project-config.jam" 549 "/home/beman/boost/develop/boost-build.jam" 550 "/home/beman/boost/develop/bootstrap.bat" 551 "/home/beman/boost/develop/bootstrap.sh" 552 "/home/beman/boost/develop/status" 553 "/home/beman/boost/develop/boost.css"</pre> 554 </td> 555 </tr> 556 </table> 557 558 559 560 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 561 <tr> 562 <td align="center"><i><b>Microsoft Windows</b></i></td> 563 </tr> 564 <tr> 565 566 <td valign="top"> 567 <pre>>tut3 \boost\develop 568"\boost\develop" is a directory containing: 569 "\boost\develop\.git" 570 "\boost\develop\.gitattributes" 571 "\boost\develop\.gitignore" 572 "\boost\develop\.gitmodules" 573 "\boost\develop\.travis.yml" 574 "\boost\develop\bin.v2" 575 "\boost\develop\boost" 576 "\boost\develop\boost-build.jam" 577 "\boost\develop\boost.css" 578 "\boost\develop\boost.png" 579 "\boost\develop\boostcpp.jam" 580 "\boost\develop\boostcpp.py" 581 "\boost\develop\bootstrap.bat" 582 "\boost\develop\bootstrap.sh" 583 "\boost\develop\doc" 584 "\boost\develop\index.htm" 585 "\boost\develop\index.html" 586 "\boost\develop\INSTALL" 587 "\boost\develop\Jamroot" 588 "\boost\develop\libs" 589 "\boost\develop\LICENSE_1_0.txt" 590 "\boost\develop\more" 591 "\boost\develop\project-config.jam" 592 "\boost\develop\rst.css" 593 "\boost\develop\stage" 594 "\boost\develop\status" 595 "\boost\develop\tools"</pre> 596 <pre>>tut3 e:\ 597boost::filesystem::status: The device is not ready: "e:\"</pre> 598 </td> 599 </tr> 600 </table> 601 602<p>Not bad, but we can make further improvements:</p> 603 604 <ul> 605 <li>The listing would be much easier to read if only the filename was 606 displayed, rather than the full path.<br> 607 </li> 608 <li>The Linux listing isn't sorted. That's because the ordering of 609 directory iteration is unspecified. Ordering depends on the underlying 610 operating system API and file system specifics. So we need to sort the 611 results ourselves. </li> 612 </ul> 613 614<p>The next sections show how those changes play out, so read on!</p> 615 616<h2><a name="Using-path-decomposition">Using path decomposition, plus sorting results</a> - (<a href="../example/tut4.cpp">tut4.cpp</a>)</h2> 617 618<p>For directories, <a href="../example/tut4.cpp">tut4.cpp</a> builds a <code> 619std::vector</code> of all the entries and then sorts it before writing to <code> 620cout</code>.</p> 621 622<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 623 <tr> 624 <td> 625 <pre><!-- include file "../example/tut4.cpp" -->#include <iostream> 626#include <vector> 627#include <algorithm> 628#include <boost/filesystem.hpp> 629using std::cout; 630using namespace boost::filesystem; 631 632int main(int argc, char* argv[]) 633{ 634 if (argc < 2) 635 { 636 cout << "Usage: tut4 path\n"; 637 return 1; 638 } 639 640 path p (argv[1]); 641 642 try 643 { 644 if (exists(p)) 645 { 646 if (is_regular_file(p)) 647 cout << p << " size is " << file_size(p) << '\n'; 648 649 else if (is_directory(p)) 650 { 651 cout << p << " is a directory containing:\n"; 652 653 std::vector<path> v; 654 655 for (auto&& x : directory_iterator(p)) 656 v.push_back(x.path()); 657 658 std::sort(v.begin(), v.end()); 659 660 for (auto&& x : v) 661 cout << " " << x.filename() << '\n'; 662 } 663 else 664 cout << p << " exists, but is not a regular file or directory\n"; 665 } 666 else 667 cout << p << " does not exist\n"; 668 } 669 670 catch (const filesystem_error& ex) 671 { 672 cout << ex.what() << '\n'; 673 } 674 675 return 0; 676}<!-- end include file --></pre> 677 </blockquote> 678 </td> 679 </tr> 680</table> 681 682 <p>The only difference between <code>tut3.cpp</code> and <code>tut4.cpp</code> is 683 what happens for directories. We changed:</p> 684 <blockquote> 685 <pre>for (const directory_entry& x : directory_iterator(p)) 686 cout << " " << x.path() << '\n';</pre> 687 </blockquote> 688 <p>to:</p> 689 <blockquote> 690 <pre>std::vector<path> v; 691 692for (auto&& x : directory_iterator(p)) 693 v.push_back(x.path()); 694 695std::sort(v.begin(), v.end()); 696 697for (auto&& x : v) 698 cout << " " << x.filename() << '\n'; 699</pre> 700 </blockquote> 701 <p> <code> 702 <a href="reference.html#path-filename">filename()</a></code> is one of 703 several class <code>path</code> decomposition functions. It extracts the 704 filename portion 705 from a path (<font face="Courier New">i.e. </font><code>"index.html"</code><font face="Courier New"> 706 from </font><code>"/home/beman/boost/trunk/index.html"</code>). These decomposition functions are 707 more fully explored in the <a href="#Class path-iterators-etc">Path iterators, observers, 708 composition, decomposition and query</a> portion of this tutorial.</p> 709 <p>The above was written as two lines of code for clarity. It could have 710 been written more concisely as:</p> 711 <blockquote> 712 <pre>v.push_back(it->path().filename()); // we only care about the filename</pre> 713 </blockquote> 714 <p>Here is the output from a test of <code><a href="../example/tut4.cpp">tut4.cpp</a></code>:</p> 715 716 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 717 <tr> 718 <td align="center"><i><b>Ubuntu Linux </b></i></td> 719 </tr> 720 <tr> 721 <td> 722 <pre>$ ./tut4 v</pre> 723 </td> 724 </tr> 725 </table> 726 727 728 729 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 730 <tr> 731 <td align="center"><i><b>Microsoft Windows</b></i></td> 732 </tr> 733 <tr> 734 <td> 735 <pre>$ ./tut4 ~/boost/develop 736"/home/beman/boost/develop" is a directory containing: 737 .git 738 .gitattributes 739 .gitignore 740 .gitmodules 741 .travis.yml 742 INSTALL 743 Jamroot 744 LICENSE_1_0.txt 745 bin.v2 746 boost 747 boost-build.jam 748 boost.css 749 boost.png 750 boostcpp.jam 751 boostcpp.py 752 bootstrap.bat 753 bootstrap.sh 754 doc 755 index.htm 756 index.html 757 libs 758 more 759 project-config.jam 760 project-config.jam.1 761 project-config.jam.2 762 rst.css 763 stage 764 status 765 tools</pre> 766 </td> 767 </tr> 768 </table> 769 770 <p>That completes the main portion of this tutorial. If you haven't already 771 worked through the <a href="#Class-path-Constructors">Class path</a> sections of this tutorial, dig into them now. 772 The <a href="#Error-reporting">Error reporting</a> section may also be of 773 interest, although it can be skipped unless you are deeply concerned about 774 error handling issues.</p> 775 776<h2><a name="Class-path-Constructors">Class path: Constructors</a>, 777including Unicode - (<a href="../example/tut5.cpp">tut5.cpp</a>)</h2> 778 779<p>Traditional C interfaces pass paths as <code>const char*</code> arguments. 780C++ interfaces may add <code>const std::string&</code> overloads, but adding 781overloads becomes untenable if wide characters, containers, and iterator ranges 782need to be supported.</p> 783<p>Passing paths as <code>const path&</code> arguments is far simpler, yet far 784more flexible because class <code>path</code> itself is far more flexible:</p> 785<ol> 786 <li>Class <code>path</code> supports multiple character types and encodings, including Unicode, to 787 ease internationalization.</li> 788 <li>Class <code>path</code> supports multiple source types, such as iterators for null terminated 789 sequences, iterator ranges, containers (including <code>std::basic_string</code>), 790 and <code><a href="reference.html#Class-directory_entry">directory_entry</a></code>'s, 791 so functions taking paths don't need to provide several overloads.</li> 792 <li>Class <code>path</code> supports both native and generic pathname formats, so programs can be 793 portable between operating systems yet use native formats where desirable.</li> 794 <li>Class <code>path</code> supplies a full set of iterators, observers, composition, 795 decomposition, and query functions, making pathname manipulations easy, 796 convenient, reliable, and portable.</li> 797</ol> 798<p>Here is how (1) and (2) work. Class path constructors, 799assignments, and appends have member templates for sources. For example, here 800are the constructors that take sources:</p> 801 802<blockquote> 803 <pre>template <class <a href="reference.html#Source">Source</a>> 804 path(Source const& source);</pre> 805 <pre>template <class InputIterator> 806 path(InputIterator begin, InputIterator end);</pre> 807</blockquote> 808<p>Let's look at a little program that shows how comfortable class <code>path</code> is with 809both narrow and wide characters in C-style strings, C++ strings, and via C++ 810iterators:</p> 811 812<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 813 <tr> 814 <td> 815 <pre><!-- include file "../example/tut5.cpp" -->#include <boost/filesystem/fstream.hpp> 816#include <string> 817#include <list> 818namespace fs = boost::filesystem; 819 820int main() 821{ 822 // \u263A is "Unicode WHITE SMILING FACE = have a nice day!" 823 std::string narrow_string ("smile2"); 824 std::wstring wide_string (L"smile2\u263A"); 825 std::list<char> narrow_list; 826 narrow_list.push_back('s'); 827 narrow_list.push_back('m'); 828 narrow_list.push_back('i'); 829 narrow_list.push_back('l'); 830 narrow_list.push_back('e'); 831 narrow_list.push_back('3'); 832 std::list<wchar_t> wide_list; 833 wide_list.push_back(L's'); 834 wide_list.push_back(L'm'); 835 wide_list.push_back(L'i'); 836 wide_list.push_back(L'l'); 837 wide_list.push_back(L'e'); 838 wide_list.push_back(L'3'); 839 wide_list.push_back(L'\u263A'); 840 841 { fs::ofstream f("smile"); } 842 { fs::ofstream f(L"smile\u263A"); } 843 { fs::ofstream f(narrow_string); } 844 { fs::ofstream f(wide_string); } 845 { fs::ofstream f(narrow_list); } 846 { fs::ofstream f(wide_list); } 847 narrow_list.pop_back(); 848 narrow_list.push_back('4'); 849 wide_list.pop_back(); 850 wide_list.pop_back(); 851 wide_list.push_back(L'4'); 852 wide_list.push_back(L'\u263A'); 853 { fs::ofstream f(fs::path(narrow_list.begin(), narrow_list.end())); } 854 { fs::ofstream f(fs::path(wide_list.begin(), wide_list.end())); } 855 856 return 0; 857}<!-- end include file --></pre> 858 </td> 859 </tr> 860</table> 861 862<p>Testing <code>tut5</code>:</p> 863 864 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 865 <tr> 866 <td align="center"><i><b>Ubuntu Linux </b></i></td> 867 </tr> 868 <tr> 869 <td valign="top"> 870 <pre>$ ./tut5 871 872$ ls smile* 873smile smile☺ smile2 smile2☺ smile3 smile3☺ smile4 smile4☺</pre> 874 </td> 875 </tr> 876 </table> 877 878 879 880 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 881 <tr> 882 <td align="center"><i><b>Microsoft Windows</b></i></td> 883 </tr> 884 <tr> 885 <td valign="top"> 886 <pre>>tut5 887 888>dir /b smile* 889smile 890smile2 891smile2☺ 892smile3 893smile3☺ 894smile4 895smile4☺ 896smile☺</pre> 897 </td> 898 </tr> 899 </table> 900 901<p>The exact appearance of the smiling face will depend on the font, 902font size, and other settings for your command line window. The above tests were 903run with out-of-the-box Ubuntu 14.04 and Windows 7, US Edition. If you don't get 904the above results, take a look at the <code><i>boost-root</i>/libs/filesystem/example/test</code> 905directory with your system's GUI file browser, such as Linux Nautilus, Mac OS X 906Finder, or Windows Explorer. These tend to be more comfortable with 907international character sets than command line interpreters.</p> 908 909 <p>Class <code>path</code> takes care of whatever character type or encoding 910 conversions are required by the particular operating system. Thus as <code> 911 tut5</code> demonstrates, it's no problem to pass a wide character string to a 912 Boost.Filesystem operational function even if the underlying operating system 913 uses narrow characters, and visa versa. And the same applies to user supplied 914 functions that take <code>const path&</code> arguments.</p> 915 916 <p>Class <code>path</code> also provides path syntax that is portable across operating systems, 917 element iterators, and observer, composition, decomposition, and query 918 functions to manipulate the elements of a path. The next section of this 919 tutorial deals with path syntax.</p> 920 921<h2><a name="Class-path-formats">Class path: Generic format vs. Native format</a></h2> 922 923<p>Class <code>path</code> deals with two different pathname 924formats - generic format and native format. For POSIX-like 925file systems, these formats are the same. But for users of Windows and 926other non-POSIX file systems, the distinction is important. Even 927programmers writing for POSIX-like systems need to understand the distinction if 928they want their code to be portable to non-POSIX systems.</p> 929 930<p>The <b>generic format</b> is the familiar <code>/my_directory/my_file.txt</code> format used by POSIX-like 931operating systems such as the Unix variants, Linux, and Mac OS X. Windows also 932recognizes the generic format, and it is the basis for the familiar Internet URL 933format. The directory 934separator character is always one or more slash characters.</p> 935 936<p>The <b>native format</b> is the format as defined by the particular 937operating system. For Windows, either the slash or the backslash can be used as 938the directory separator character, so <code>/my_directory\my_file.txt</code> 939would work fine. Of course, if you write that in a C++ string literal, it 940becomes <code>"/my_directory\\my_file.txt"</code>.</p> 941 942<p>If a drive specifier or a backslash appears 943in a pathname on a Windows system, it is always treated as the native format.</p> 944 945<p>Class <code>path</code> has observer functions that allow you to 946obtain the string representation of a path object in either the native format 947or the generic format. See the <a href="#Class path-iterators-etc">next section</a> 948for how that plays out.</p> 949 950 <p>The distinction between generic format and native format is important when 951 communicating with native C-style API's and with users. Both tend to expect 952 paths in the native format and may be confused by the generic format. The generic 953 format is great, however, for writing portable programs that work regardless 954 of operating system.</p> 955 956 <p>The next section covers class <code>path</code> observers, composition, 957 decomposition, query, and iteration over the elements of a path.</p> 958 959<h2><a name="Class path-iterators-etc">Class path: Iterators, observers, composition, decomposition, and query</a> 960- (<a href="../example/path_info.cpp">path_info.cpp</a>)</h2> 961 962<p>The <code><a href="../example/path_info.cpp">path_info.cpp</a></code> program is handy for learning how class <code>path</code> 963iterators, 964observers, composition, decomposition, and query functions work on your system. 965It is one of the programs built by the <code>build.sh</code> and <code>build.bat</code> 966scripts:</p> 967 968 969<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 970 <tr> 971 <td> 972 <pre><!-- include file "../example/path_info.cpp" -->#include <iostream> 973#include <boost/filesystem.hpp> 974using namespace std; 975using namespace boost::filesystem; 976 977const char * say_what(bool b) { return b ? "true" : "false"; } 978 979int main(int argc, char* argv[]) 980{ 981 if (argc < 2) 982 { 983 cout << "Usage: path_info path-element [path-element...]\n" 984 "Composes a path via operator/= from one or more path-element arguments\n" 985 "Example: path_info foo/bar baz\n" 986# ifdef BOOST_POSIX_API 987 " would report info about the composed path foo/bar/baz\n"; 988# else // BOOST_WINDOWS_API 989 " would report info about the composed path foo/bar\\baz\n"; 990# endif 991 return 1; 992 } 993 994 path p; 995 for (; argc > 1; --argc, ++argv) 996 p /= argv[1]; // compose path p from the command line arguments 997 998 cout << "\ncomposed path:\n"; 999 cout << " operator<<()---------: " << p << "\n"; 1000 cout << " make_preferred()-----: " << p.make_preferred() << "\n"; 1001 1002 cout << "\nelements:\n"; 1003 for (auto element : p) 1004 cout << " " << element << '\n'; 1005 1006 cout << "\nobservers, native format:" << endl; 1007# ifdef BOOST_POSIX_API 1008 cout << " native()-------------: " << p.native() << endl; 1009 cout << " c_str()--------------: " << p.c_str() << endl; 1010# else // BOOST_WINDOWS_API 1011 wcout << L" native()-------------: " << p.native() << endl; 1012 wcout << L" c_str()--------------: " << p.c_str() << endl; 1013# endif 1014 cout << " string()-------------: " << p.string() << endl; 1015 wcout << L" wstring()------------: " << p.wstring() << endl; 1016 1017 cout << "\nobservers, generic format:\n"; 1018 cout << " generic_string()-----: " << p.generic_string() << endl; 1019 wcout << L" generic_wstring()----: " << p.generic_wstring() << endl; 1020 1021 cout << "\ndecomposition:\n"; 1022 cout << " root_name()----------: " << p.root_name() << '\n'; 1023 cout << " root_directory()-----: " << p.root_directory() << '\n'; 1024 cout << " root_path()----------: " << p.root_path() << '\n'; 1025 cout << " relative_path()------: " << p.relative_path() << '\n'; 1026 cout << " parent_path()--------: " << p.parent_path() << '\n'; 1027 cout << " filename()-----------: " << p.filename() << '\n'; 1028 cout << " stem()---------------: " << p.stem() << '\n'; 1029 cout << " extension()----------: " << p.extension() << '\n'; 1030 1031 cout << "\nquery:\n"; 1032 cout << " empty()--------------: " << say_what(p.empty()) << '\n'; 1033 cout << " is_absolute()--------: " << say_what(p.is_absolute()) << '\n'; 1034 cout << " has_root_name()------: " << say_what(p.has_root_name()) << '\n'; 1035 cout << " has_root_directory()-: " << say_what(p.has_root_directory()) << '\n'; 1036 cout << " has_root_path()------: " << say_what(p.has_root_path()) << '\n'; 1037 cout << " has_relative_path()--: " << say_what(p.has_relative_path()) << '\n'; 1038 cout << " has_parent_path()----: " << say_what(p.has_parent_path()) << '\n'; 1039 cout << " has_filename()-------: " << say_what(p.has_filename()) << '\n'; 1040 cout << " has_stem()-----------: " << say_what(p.has_stem()) << '\n'; 1041 cout << " has_extension()------: " << say_what(p.has_extension()) << '\n'; 1042 1043 return 0; 1044}<!-- end include file --></pre> 1045 </td> 1046 </tr> 1047</table> 1048 1049 1050<p>Run the examples below on your system, and try some different path arguments 1051as we go along. Here is the invocation we will talk about in detail:</p> 1052 1053 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 1054 <tr> 1055 <td align="center"><i><b>Ubuntu Linux </b></i></td> 1056 </tr> 1057 <tr> 1058 <td> 1059 <pre>$ ./path_info /foo bar baa.txt 1060 1061composed path: 1062 operator<<()---------: "/foo/bar/baa.txt" 1063 make_preferred()-----: "/foo/bar/baa.txt" 1064 1065elements: 1066 "/" 1067 "foo" 1068 "bar" 1069 "baa.txt" 1070 1071observers, native format: 1072 native()-------------: /foo/bar/baa.txt 1073 c_str()--------------: /foo/bar/baa.txt 1074 string()-------------: /foo/bar/baa.txt 1075 wstring()------------: /foo/bar/baa.txt 1076 1077observers, generic format: 1078 generic_string()-----: /foo/bar/baa.txt 1079 generic_wstring()----: /foo/bar/baa.txt 1080 1081decomposition: 1082 root_name()----------: "" 1083 root_directory()-----: "/" 1084 root_path()----------: "/" 1085 relative_path()------: "foo/bar/baa.txt" 1086 parent_path()--------: "/foo/bar" 1087 filename()-----------: "baa.txt" 1088 stem()---------------: "baa" 1089 extension()----------: ".txt" 1090 1091query: 1092 empty()--------------: false 1093 is_absolute()--------: true 1094 has_root_name()------: false 1095 has_root_directory()-: true 1096 has_root_path()------: true 1097 has_relative_path()--: true 1098 has_parent_path()----: true 1099 has_filename()-------: true 1100 has_stem()-----------: true 1101 has_extension()------: true</pre> 1102 </td> 1103 </tr> 1104 </table> 1105 1106 1107 1108 <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 1109 <tr> 1110 <td align="center"><i><b>Microsoft Windows</b></i></td> 1111 </tr> 1112 <tr> 1113 <td> 1114 <pre>>path_info \foo bar baa.txt 1115 1116composed path: 1117operator<<()---------: "\foo\bar\baa.txt" 1118make_preferred()-----: "\foo\bar\baa.txt" 1119 1120elements: 1121 "/" 1122 "foo" 1123 "bar" 1124 "baa.txt" 1125 1126observers, native format: 1127native()-------------: \foo\bar\baa.txt 1128c_str()--------------: \foo\bar\baa.txt 1129string()-------------: \foo\bar\baa.txt 1130wstring()------------: \foo\bar\baa.txt 1131 1132observers, generic format: 1133generic_string()-----: /foo/bar/baa.txt 1134generic_wstring()----: /foo/bar/baa.txt 1135 1136decomposition: 1137root_name()----------: "" 1138root_directory()-----: "\" 1139root_path()----------: "\" 1140relative_path()------: "foo\bar\baa.txt" 1141parent_path()--------: "\foo\bar" 1142filename()-----------: "baa.txt" 1143stem()---------------: "baa" 1144extension()----------: ".txt" 1145 1146query: 1147empty()--------------: false 1148is_absolute()--------: false 1149has_root_name()------: false 1150has_root_directory()-: true 1151has_root_path()------: true 1152has_relative_path()--: true 1153has_parent_path()----: true 1154has_filename()-------: true 1155has_stem()-----------: true 1156has_extension()------: true</pre> 1157 </td> 1158 </tr> 1159 </table> 1160 1161<p>We will go through the above code in detail to gain a better 1162understanding of what is going on.</p> 1163 1164<p dir="ltr">A common need is to compose a path from its constituent 1165directories. Class <code>path</code> uses <code>/</code> and <code>/=</code> operators to 1166append elements. That's a reminder 1167that these operations append the operating system's preferred directory 1168separator if needed. The preferred 1169directory separator is a slash on POSIX-like systems, and a backslash on 1170Windows-like systems.</p> 1171 1172<p dir="ltr">That's what this code does before displaying the resulting <code> 1173path p</code> using the <code>class path</code> stream inserter: </p> 1174 1175 1176<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 1177 <tr> 1178 <td> 1179 <pre><!-- include file "../example/path_info.cpp" --> path p; 1180 for (; argc > 1; --argc, ++argv) 1181 p /= argv[1]; // compose path p from the command line arguments 1182 1183 cout << "\ncomposed path:\n"; 1184 cout << " operator<<()---------: " << p << "\n"; 1185 cout << " make_preferred()-----: " << p.make_preferred() << "\n";</pre> 1186 </td> 1187 </tr> 1188</table> 1189 1190 1191<p>One abstraction for thinking about a path is as a sequence of elements, where 1192the elements are directory and file names. To support this abstraction, class 1193<code>path</code> provides STL-like iterators and also <code>begin()</code> 1194and <code>end()</code> functions.</p> 1195 1196<p>Here is the code that produced the list of elements in the above output listing:</p> 1197 1198<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 1199 <tr> 1200 <td> 1201 <pre>cout << "\nelements:\n"; 1202for (auto element : p) 1203 cout << " " << element << '\n';</pre> 1204 </td> 1205 </tr> 1206</table> 1207 1208<p>Let's look at class path observer functions:</p> 1209 1210 1211<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 1212 <tr> 1213 <td> 1214 <pre><!-- include file "../example/path_info.cpp" --> cout << "\nobservers, native format:" << endl; 1215# ifdef BOOST_POSIX_API 1216 cout << " native()-------------: " << p.native() << endl; 1217 cout << " c_str()--------------: " << p.c_str() << endl; 1218# else // BOOST_WINDOWS_API 1219 wcout << L" native()-------------: " << p.native() << endl; 1220 wcout << L" c_str()--------------: " << p.c_str() << endl; 1221# endif 1222 cout << " string()-------------: " << p.string() << endl; 1223 wcout << L" wstring()------------: " << p.wstring() << endl; 1224 1225 cout << "\nobservers, generic format:\n"; 1226 cout << " generic_string()-----: " << p.generic_string() << endl; 1227 wcout << L" generic_wstring()----: " << p.generic_wstring() << endl;</pre> 1228 </td> 1229 </tr> 1230</table> 1231 1232 1233<p>Native format observers should be used when interacting with the 1234operating system or with users; that's what they expect.</p> 1235 1236<p>Generic format observers should be used when the results need to be 1237portable and uniform regardless of the operating system.</p> 1238 1239<p><code>path</code> objects always hold pathnames in the native 1240format, but otherwise leave them unchanged from their source. The 1241<a href="reference.html#preferred">preferred()</a> function will convert to the 1242preferred form, if the native format has several forms. Thus on Windows, it will 1243convert slashes to backslashes.</p> 1244 1245<p>Moving on to decomposition:</p> 1246 1247 1248<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 1249 <tr> 1250 <td> 1251 <pre><!-- include file "../example/path_info.cpp" --> cout << "\ndecomposition:\n"; 1252 cout << " root_name()----------: " << p.root_name() << '\n'; 1253 cout << " root_directory()-----: " << p.root_directory() << '\n'; 1254 cout << " root_path()----------: " << p.root_path() << '\n'; 1255 cout << " relative_path()------: " << p.relative_path() << '\n'; 1256 cout << " parent_path()--------: " << p.parent_path() << '\n'; 1257 cout << " filename()-----------: " << p.filename() << '\n'; 1258 cout << " stem()---------------: " << p.stem() << '\n'; 1259 cout << " extension()----------: " << p.extension() << '\n';</pre> 1260 </td> 1261 </tr> 1262</table> 1263 1264 1265<p> And, finally, query functions:</p> 1266 1267 1268<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> 1269 <tr> 1270 <td> 1271 <pre><!-- include file "../example/path_info.cpp" --> cout << "\nquery:\n"; 1272 cout << " empty()--------------: " << say_what(p.empty()) << '\n'; 1273 cout << " is_absolute()--------: " << say_what(p.is_absolute()) << '\n'; 1274 cout << " has_root_name()------: " << say_what(p.has_root_name()) << '\n'; 1275 cout << " has_root_directory()-: " << say_what(p.has_root_directory()) << '\n'; 1276 cout << " has_root_path()------: " << say_what(p.has_root_path()) << '\n'; 1277 cout << " has_relative_path()--: " << say_what(p.has_relative_path()) << '\n'; 1278 cout << " has_parent_path()----: " << say_what(p.has_parent_path()) << '\n'; 1279 cout << " has_filename()-------: " << say_what(p.has_filename()) << '\n'; 1280 cout << " has_stem()-----------: " << say_what(p.has_stem()) << '\n'; 1281 cout << " has_extension()------: " << say_what(p.has_extension()) << '\n';</pre> 1282 </td> 1283 </tr> 1284</table> 1285 1286 1287<p>These are pretty self-evident, but do note the difference in the 1288result of <code>is_absolute()</code> between Linux and Windows. Because there is 1289no root name (i.e. drive specifier or network name), a lone slash (or backslash) 1290is a relative path on Windows but an absolute path on POSIX-like operating 1291systems. </p> 1292 1293 <h2><a name="Error-reporting">Error reporting</a></h2> 1294 1295 <p>The Boost.Filesystem <code>file_size</code> function, like many of the 1296 operational functions, has two overloads:</p> 1297 1298 <blockquote> 1299 <pre>uintmax_t <a name="file_size">file_size</a>(const path& p); 1300uintmax_t <a name="file_size2">file_size</a>(const path& p, system::error_code& ec);</pre> 1301</blockquote> 1302<p>The only significant difference between the two is how they report errors.</p> 1303<p>The 1304 first signature will throw exceptions to report errors. A <code> 1305<a href="reference.html#Class-filesystem_error">filesystem_error</a></code> exception will be thrown 1306on an 1307 operational error. <code>filesystem_error</code> is derived from <code>std::runtime_error</code>. 1308It has a 1309 member function to obtain the <code> 1310<a href="../../system/doc/reference.html#Class-error_code">error_code</a></code> reported by the source 1311 of the error. It also has member functions to obtain the path or paths that caused 1312 the error.</p> 1313 1314 <blockquote> 1315 1316 <p><b>Motivation for the second signature:</b> Throwing exceptions on errors was the entire error reporting story for the earliest versions of 1317 Boost.Filesystem, and indeed throwing exceptions on errors works very well for 1318 many applications. But user reports trickled in that some code became so 1319 littered with try and catch blocks as to be unreadable and unmaintainable. In 1320 some applications I/O errors aren't exceptional, and that's the use case for 1321 the second signature.</p> 1322 1323 </blockquote> 1324 1325 <p>Functions with a <code>system::error_code&</code> argument set that 1326 argument to report operational error status, and so do not throw exceptions when I/O 1327 related errors occur. For a full explanation, see 1328 <a href="reference.html#Error-reporting">Error reporting</a> in the reference 1329 documentation. </p> 1330 1331<hr> 1332<p>© Copyright Beman Dawes 2010, 2015</p> 1333<p>Distributed under the Boost Software License, Version 1.0. See 1334<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p> 1335<p>Revised 1336<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->07 August 2017<!--webbot bot="Timestamp" endspan i-checksum="31490" --></p> 1337 1338</body> 1339 1340</html> 1341