• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &nbsp;&nbsp;
29    <a href="tutorial.html">Tutorial</a> &nbsp;&nbsp;
30    <a href="reference.html">Reference</a> &nbsp;&nbsp;
31    <a href="faq.htm">FAQ</a> &nbsp;&nbsp;
32    <a href="release_history.html">Releases</a> &nbsp;&nbsp;
33    <a href="portability_guide.htm">Portability</a> &nbsp;&nbsp;
34    <a href="v3.html">V3 Intro</a> &nbsp;&nbsp;
35    <a href="v3_design.html">V3 Design</a> &nbsp;&nbsp;
36    <a href="deprecated.html">Deprecated</a> &nbsp;&nbsp;
37    <a href="issue_reporting.html">Bug Reports </a>&nbsp;&nbsp;
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  &nbsp;
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>&gt;cd <i><b>boost-root</b></i>\libs\filesystem\example\test
115
116&gt;setup
117Copying example programs...
118
119&gt;build
120Compiling example programs...
121
122&gt;tut1
123Usage: tut1 path</pre>
124      </td>
125    </tr>
126  </table>
127
128<p>If the <code>tut1</code> command outputs &quot;<code>Usage: tut1 path</code>&quot;, 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&nbsp;</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 &lt;iostream&gt;
156#include &lt;boost/filesystem.hpp&gt;
157using namespace boost::filesystem;
158
159int main(int argc, char* argv[])
160{
161  if (argc &lt; 2)
162  {
163    std::cout &lt;&lt; &quot;Usage: tut1 path\n&quot;;
164    return 1;
165  }
166  std::cout &lt;&lt; argv[1] &lt;&lt; &quot; &quot; &lt;&lt; file_size(argv[1]) &lt;&lt; '\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&amp; 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  &nbsp;
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>&gt;tut1 tut1.cpp
213tut1.cpp 592
214
215&gt;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>&quot;\n&quot;</code> line endings, while the Windows tests
225used <code>&quot;\r\n&quot;</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 &#39;boost::filesystem::filesystem_error&#39;
238what(): boost::filesystem::file_size: No such file or directory: &quot;foo&quot;
239Aborted (core dumped)</pre>
240      </td>
241    </tr>
242  </table>
243
244&nbsp;
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>&gt;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 &#39;boost::filesystem::filesystem_error&#39;
274what(): boost::filesystem::file_size: Operation not permitted: &quot;.&quot;
275Aborted (core dumped)</pre>
276      </td>
277    </tr>
278  </table>
279
280  &nbsp;
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>&gt;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 &lt;iostream&gt;
317#include &lt;boost/filesystem.hpp&gt;
318using namespace std;
319using namespace boost::filesystem;
320
321int main(int argc, char* argv[])
322{
323  if (argc &lt; 2)
324  {
325    cout &lt;&lt; &quot;Usage: tut2 path\n&quot;;
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 &lt;&lt; p &lt;&lt; &quot; size is &quot; &lt;&lt; file_size(p) &lt;&lt; '\n';
335
336    else if (is_directory(p))      // is path p a directory?
337      cout &lt;&lt; p &lt;&lt; &quot; is a directory\n&quot;;
338
339    else
340      cout &lt;&lt; p &lt;&lt; &quot; exists, but is not a regular file or directory\n&quot;;
341  }
342  else
343    cout &lt;&lt; p &lt;&lt; &quot; does not exist\n&quot;;
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&quot;tut2.cpp&quot; size is 997
361
362$ ./tut2 foo
363&quot;foo&quot; does not exist
364
365$ ./tut2 .
366&quot;.&quot; is a directory</pre>
367      </td>
368    </tr>
369  </table>
370
371&nbsp;
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>&gt;tut2 tut2.cpp
380tut2.cpp size is 1039
381
382&gt;tut2 foo
383&quot;foo&quot; does not exist
384
385&gt;tut2 .
386&quot;.&quot; 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&gt;'
409   what(): boost::filesystem::status: Permission denied:
410     &quot;/home/jane/foo&quot;
411Aborted</pre>
412      </td>
413     </tr>
414  </table>
415
416  &nbsp;
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>&gt;dir e:\
425The device is not ready.
426
427&gt;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.&nbsp; 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 &lt;iostream&gt;
466#include &lt;boost/filesystem.hpp&gt;
467using std::cout;
468using namespace boost::filesystem;
469
470int main(int argc, char* argv[])
471{
472  if (argc &lt; 2)
473  {
474    cout &lt;&lt; &quot;Usage: tut3 path\n&quot;;
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 &lt;&lt; p &lt;&lt; &quot; size is &quot; &lt;&lt; file_size(p) &lt;&lt; '\n';
486
487      else if (is_directory(p))
488      {
489        cout &lt;&lt; p &lt;&lt; &quot; is a directory containing:\n&quot;;
490
491        for (directory_entry&amp; x : directory_iterator(p))
492          cout &lt;&lt; &quot;    &quot; &lt;&lt; x.path() &lt;&lt; '\n';
493      }
494      else
495        cout &lt;&lt; p &lt;&lt; &quot; exists, but is not a regular file or directory\n&quot;;
496    }
497    else
498      cout &lt;&lt; p &lt;&lt; &quot; does not exist\n&quot;;
499  }
500
501  catch (const filesystem_error&amp; ex)
502  {
503    cout &lt;&lt; ex.what() &lt;&lt; '\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    &quot;/home/beman/boost/develop&quot; is a directory containing:
524    &quot;/home/beman/boost/develop/rst.css&quot;
525    &quot;/home/beman/boost/develop/boost&quot;
526    &quot;/home/beman/boost/develop/boost.png&quot;
527    &quot;/home/beman/boost/develop/libs&quot;
528    &quot;/home/beman/boost/develop/doc&quot;
529    &quot;/home/beman/boost/develop/project-config.jam.2&quot;
530    &quot;/home/beman/boost/develop/.gitmodules&quot;
531    &quot;/home/beman/boost/develop/boostcpp.py&quot;
532    &quot;/home/beman/boost/develop/.travis.yml&quot;
533    &quot;/home/beman/boost/develop/.gitattributes&quot;
534    &quot;/home/beman/boost/develop/index.htm&quot;
535    &quot;/home/beman/boost/develop/index.html&quot;
536    &quot;/home/beman/boost/develop/bjam&quot;
537    &quot;/home/beman/boost/develop/project-config.jam.1&quot;
538    &quot;/home/beman/boost/develop/LICENSE_1_0.txt&quot;
539    &quot;/home/beman/boost/develop/.git&quot;
540    &quot;/home/beman/boost/develop/tools&quot;
541    &quot;/home/beman/boost/develop/stage&quot;
542    &quot;/home/beman/boost/develop/boostcpp.jam&quot;
543    &quot;/home/beman/boost/develop/Jamroot&quot;
544    &quot;/home/beman/boost/develop/.gitignore&quot;
545    &quot;/home/beman/boost/develop/INSTALL&quot;
546    &quot;/home/beman/boost/develop/more&quot;
547    &quot;/home/beman/boost/develop/bin.v2&quot;
548    &quot;/home/beman/boost/develop/project-config.jam&quot;
549    &quot;/home/beman/boost/develop/boost-build.jam&quot;
550    &quot;/home/beman/boost/develop/bootstrap.bat&quot;
551    &quot;/home/beman/boost/develop/bootstrap.sh&quot;
552    &quot;/home/beman/boost/develop/status&quot;
553    &quot;/home/beman/boost/develop/boost.css&quot;</pre>
554    </td>
555     </tr>
556  </table>
557
558  &nbsp;
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>&gt;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>&gt;tut3 e:\
597boost::filesystem::status: The device is not ready: &quot;e:\&quot;</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&nbsp;</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 &lt;iostream&gt;
626#include &lt;vector&gt;
627#include &lt;algorithm&gt;
628#include &lt;boost/filesystem.hpp&gt;
629using std::cout;
630using namespace boost::filesystem;
631
632int main(int argc, char* argv[])
633{
634  if (argc &lt; 2)
635  {
636    cout &lt;&lt; &quot;Usage: tut4 path\n&quot;;
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 &lt;&lt; p &lt;&lt; &quot; size is &quot; &lt;&lt; file_size(p) &lt;&lt; '\n';
648
649      else if (is_directory(p))
650      {
651        cout &lt;&lt; p &lt;&lt; &quot; is a directory containing:\n&quot;;
652
653        std::vector&lt;path&gt; v;
654
655        for (auto&amp;&amp; x : directory_iterator(p))
656          v.push_back(x.path());
657
658        std::sort(v.begin(), v.end());
659
660        for (auto&amp;&amp; x : v)
661          cout &lt;&lt; &quot;    &quot; &lt;&lt; x.filename() &lt;&lt; '\n';
662      }
663      else
664        cout &lt;&lt; p &lt;&lt; &quot; exists, but is not a regular file or directory\n&quot;;
665    }
666    else
667      cout &lt;&lt; p &lt;&lt; &quot; does not exist\n&quot;;
668  }
669
670  catch (const filesystem_error&amp; ex)
671  {
672    cout &lt;&lt; ex.what() &lt;&lt; '\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&amp; x : directory_iterator(p))
686  cout &lt;&lt; &quot; &quot; &lt;&lt; x.path() &lt;&lt; &#39;\n&#39;;</pre>
687    </blockquote>
688    <p>to:</p>
689    <blockquote>
690      <pre>std::vector&lt;path&gt; v;
691
692for (auto&amp;&amp; x : directory_iterator(p))
693  v.push_back(x.path());
694
695std::sort(v.begin(), v.end());
696
697for (auto&amp;&amp; x : v)
698  cout &lt;&lt; &quot; &quot; &lt;&lt; x.filename() &lt;&lt; &#39;\n&#39;;
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>&quot;index.html&quot;</code><font face="Courier New">
706    from </font><code>&quot;/home/beman/boost/trunk/index.html&quot;</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-&gt;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&nbsp;
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&amp;</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&amp;</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 &lt;class <a href="reference.html#Source">Source</a>&gt;
804  path(Source const&amp; source);</pre>
805  <pre>template &lt;class InputIterator&gt;
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 &lt;boost/filesystem/fstream.hpp&gt;
816#include &lt;string&gt;
817#include &lt;list&gt;
818namespace fs = boost::filesystem;
819
820int main()
821{
822  // \u263A is &quot;Unicode WHITE SMILING FACE = have a nice day!&quot;
823  std::string narrow_string (&quot;smile2&quot;);
824  std::wstring wide_string (L&quot;smile2\u263A&quot;);
825  std::list&lt;char&gt; 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&lt;wchar_t&gt; 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(&quot;smile&quot;); }
842  { fs::ofstream f(L&quot;smile\u263A&quot;); }
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&#9786; smile2 smile2&#9786; smile3 smile3&#9786; smile4 smile4&#9786;</pre>
874      </td>
875    </tr>
876  </table>
877
878&nbsp;
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>&gt;tut5
887
888&gt;dir /b smile*
889smile
890smile2
891smile2&#9786;
892smile3
893smile3&#9786;
894smile4
895smile4&#9786;
896smile&#9786;</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&amp;</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>&quot;/my_directory\\my_file.txt&quot;</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 &lt;iostream&gt;
973#include &lt;boost/filesystem.hpp&gt;
974using namespace std;
975using namespace boost::filesystem;
976
977const char * say_what(bool b) { return b ? &quot;true&quot; : &quot;false&quot;; }
978
979int main(int argc, char* argv[])
980{
981  if (argc &lt; 2)
982  {
983    cout &lt;&lt; &quot;Usage: path_info path-element [path-element...]\n&quot;
984            &quot;Composes a path via operator/= from one or more path-element arguments\n&quot;
985            &quot;Example: path_info foo/bar baz\n&quot;
986#            ifdef BOOST_POSIX_API
987            &quot;         would report info about the composed path foo/bar/baz\n&quot;;
988#            else  // BOOST_WINDOWS_API
989            &quot;         would report info about the composed path foo/bar\\baz\n&quot;;
990#            endif
991    return 1;
992  }
993
994  path p;
995  for (; argc &gt; 1; --argc, ++argv)
996    p /= argv[1];  // compose path p from the command line arguments
997
998  cout  &lt;&lt;  &quot;\ncomposed path:\n&quot;;
999  cout  &lt;&lt;  &quot;  operator&lt;&lt;()---------: &quot; &lt;&lt; p &lt;&lt; &quot;\n&quot;;
1000  cout  &lt;&lt;  &quot;  make_preferred()-----: &quot; &lt;&lt; p.make_preferred() &lt;&lt; &quot;\n&quot;;
1001
1002  cout &lt;&lt; &quot;\nelements:\n&quot;;
1003  for (auto element : p)
1004    cout &lt;&lt; &quot;  &quot; &lt;&lt; element &lt;&lt; '\n';
1005
1006  cout  &lt;&lt;  &quot;\nobservers, native format:&quot; &lt;&lt; endl;
1007# ifdef BOOST_POSIX_API
1008  cout  &lt;&lt;  &quot;  native()-------------: &quot; &lt;&lt; p.native() &lt;&lt; endl;
1009  cout  &lt;&lt;  &quot;  c_str()--------------: &quot; &lt;&lt; p.c_str() &lt;&lt; endl;
1010# else  // BOOST_WINDOWS_API
1011  wcout &lt;&lt; L&quot;  native()-------------: &quot; &lt;&lt; p.native() &lt;&lt; endl;
1012  wcout &lt;&lt; L&quot;  c_str()--------------: &quot; &lt;&lt; p.c_str() &lt;&lt; endl;
1013# endif
1014  cout  &lt;&lt;  &quot;  string()-------------: &quot; &lt;&lt; p.string() &lt;&lt; endl;
1015  wcout &lt;&lt; L&quot;  wstring()------------: &quot; &lt;&lt; p.wstring() &lt;&lt; endl;
1016
1017  cout  &lt;&lt;  &quot;\nobservers, generic format:\n&quot;;
1018  cout  &lt;&lt;  &quot;  generic_string()-----: &quot; &lt;&lt; p.generic_string() &lt;&lt; endl;
1019  wcout &lt;&lt; L&quot;  generic_wstring()----: &quot; &lt;&lt; p.generic_wstring() &lt;&lt; endl;
1020
1021  cout  &lt;&lt;  &quot;\ndecomposition:\n&quot;;
1022  cout  &lt;&lt;  &quot;  root_name()----------: &quot; &lt;&lt; p.root_name() &lt;&lt; '\n';
1023  cout  &lt;&lt;  &quot;  root_directory()-----: &quot; &lt;&lt; p.root_directory() &lt;&lt; '\n';
1024  cout  &lt;&lt;  &quot;  root_path()----------: &quot; &lt;&lt; p.root_path() &lt;&lt; '\n';
1025  cout  &lt;&lt;  &quot;  relative_path()------: &quot; &lt;&lt; p.relative_path() &lt;&lt; '\n';
1026  cout  &lt;&lt;  &quot;  parent_path()--------: &quot; &lt;&lt; p.parent_path() &lt;&lt; '\n';
1027  cout  &lt;&lt;  &quot;  filename()-----------: &quot; &lt;&lt; p.filename() &lt;&lt; '\n';
1028  cout  &lt;&lt;  &quot;  stem()---------------: &quot; &lt;&lt; p.stem() &lt;&lt; '\n';
1029  cout  &lt;&lt;  &quot;  extension()----------: &quot; &lt;&lt; p.extension() &lt;&lt; '\n';
1030
1031  cout  &lt;&lt;  &quot;\nquery:\n&quot;;
1032  cout  &lt;&lt;  &quot;  empty()--------------: &quot; &lt;&lt; say_what(p.empty()) &lt;&lt; '\n';
1033  cout  &lt;&lt;  &quot;  is_absolute()--------: &quot; &lt;&lt; say_what(p.is_absolute()) &lt;&lt; '\n';
1034  cout  &lt;&lt;  &quot;  has_root_name()------: &quot; &lt;&lt; say_what(p.has_root_name()) &lt;&lt; '\n';
1035  cout  &lt;&lt;  &quot;  has_root_directory()-: &quot; &lt;&lt; say_what(p.has_root_directory()) &lt;&lt; '\n';
1036  cout  &lt;&lt;  &quot;  has_root_path()------: &quot; &lt;&lt; say_what(p.has_root_path()) &lt;&lt; '\n';
1037  cout  &lt;&lt;  &quot;  has_relative_path()--: &quot; &lt;&lt; say_what(p.has_relative_path()) &lt;&lt; '\n';
1038  cout  &lt;&lt;  &quot;  has_parent_path()----: &quot; &lt;&lt; say_what(p.has_parent_path()) &lt;&lt; '\n';
1039  cout  &lt;&lt;  &quot;  has_filename()-------: &quot; &lt;&lt; say_what(p.has_filename()) &lt;&lt; '\n';
1040  cout  &lt;&lt;  &quot;  has_stem()-----------: &quot; &lt;&lt; say_what(p.has_stem()) &lt;&lt; '\n';
1041  cout  &lt;&lt;  &quot;  has_extension()------: &quot; &lt;&lt; say_what(p.has_extension()) &lt;&lt; '\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  &nbsp;
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>&gt;path_info \foo bar baa.txt
1115
1116composed path:
1117operator&lt;&lt;()---------: &quot;\foo\bar\baa.txt&quot;
1118make_preferred()-----: &quot;\foo\bar\baa.txt&quot;
1119
1120elements:
1121  &quot;/&quot;
1122  &quot;foo&quot;
1123  &quot;bar&quot;
1124  &quot;baa.txt&quot;
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()----------: &quot;&quot;
1138root_directory()-----: &quot;\&quot;
1139root_path()----------: &quot;\&quot;
1140relative_path()------: &quot;foo\bar\baa.txt&quot;
1141parent_path()--------: &quot;\foo\bar&quot;
1142filename()-----------: &quot;baa.txt&quot;
1143stem()---------------: &quot;baa&quot;
1144extension()----------: &quot;.txt&quot;
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&#39;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 &gt; 1; --argc, ++argv)
1181    p /= argv[1];  // compose path p from the command line arguments
1182
1183  cout  &lt;&lt;  &quot;\ncomposed path:\n&quot;;
1184  cout  &lt;&lt;  &quot;  operator&lt;&lt;()---------: &quot; &lt;&lt; p &lt;&lt; &quot;\n&quot;;
1185  cout  &lt;&lt;  &quot;  make_preferred()-----: &quot; &lt;&lt; p.make_preferred() &lt;&lt; &quot;\n&quot;;</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&nbsp; 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 &lt;&lt; &quot;\nelements:\n&quot;;
1202for (auto element : p)
1203  cout &lt;&lt; &quot; &quot; &lt;&lt; element &lt;&lt; &#39;\n&#39;;</pre>
1204    </td>
1205  </tr>
1206</table>
1207
1208<p>Let&#39;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  &lt;&lt;  &quot;\nobservers, native format:&quot; &lt;&lt; endl;
1215# ifdef BOOST_POSIX_API
1216  cout  &lt;&lt;  &quot;  native()-------------: &quot; &lt;&lt; p.native() &lt;&lt; endl;
1217  cout  &lt;&lt;  &quot;  c_str()--------------: &quot; &lt;&lt; p.c_str() &lt;&lt; endl;
1218# else  // BOOST_WINDOWS_API
1219  wcout &lt;&lt; L&quot;  native()-------------: &quot; &lt;&lt; p.native() &lt;&lt; endl;
1220  wcout &lt;&lt; L&quot;  c_str()--------------: &quot; &lt;&lt; p.c_str() &lt;&lt; endl;
1221# endif
1222  cout  &lt;&lt;  &quot;  string()-------------: &quot; &lt;&lt; p.string() &lt;&lt; endl;
1223  wcout &lt;&lt; L&quot;  wstring()------------: &quot; &lt;&lt; p.wstring() &lt;&lt; endl;
1224
1225  cout  &lt;&lt;  &quot;\nobservers, generic format:\n&quot;;
1226  cout  &lt;&lt;  &quot;  generic_string()-----: &quot; &lt;&lt; p.generic_string() &lt;&lt; endl;
1227  wcout &lt;&lt; L&quot;  generic_wstring()----: &quot; &lt;&lt; p.generic_wstring() &lt;&lt; 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  &lt;&lt;  &quot;\ndecomposition:\n&quot;;
1252  cout  &lt;&lt;  &quot;  root_name()----------: &quot; &lt;&lt; p.root_name() &lt;&lt; '\n';
1253  cout  &lt;&lt;  &quot;  root_directory()-----: &quot; &lt;&lt; p.root_directory() &lt;&lt; '\n';
1254  cout  &lt;&lt;  &quot;  root_path()----------: &quot; &lt;&lt; p.root_path() &lt;&lt; '\n';
1255  cout  &lt;&lt;  &quot;  relative_path()------: &quot; &lt;&lt; p.relative_path() &lt;&lt; '\n';
1256  cout  &lt;&lt;  &quot;  parent_path()--------: &quot; &lt;&lt; p.parent_path() &lt;&lt; '\n';
1257  cout  &lt;&lt;  &quot;  filename()-----------: &quot; &lt;&lt; p.filename() &lt;&lt; '\n';
1258  cout  &lt;&lt;  &quot;  stem()---------------: &quot; &lt;&lt; p.stem() &lt;&lt; '\n';
1259  cout  &lt;&lt;  &quot;  extension()----------: &quot; &lt;&lt; p.extension() &lt;&lt; '\n';</pre>
1260    </td>
1261  </tr>
1262</table>
1263
1264
1265<p>&nbsp;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  &lt;&lt;  &quot;\nquery:\n&quot;;
1272  cout  &lt;&lt;  &quot;  empty()--------------: &quot; &lt;&lt; say_what(p.empty()) &lt;&lt; '\n';
1273  cout  &lt;&lt;  &quot;  is_absolute()--------: &quot; &lt;&lt; say_what(p.is_absolute()) &lt;&lt; '\n';
1274  cout  &lt;&lt;  &quot;  has_root_name()------: &quot; &lt;&lt; say_what(p.has_root_name()) &lt;&lt; '\n';
1275  cout  &lt;&lt;  &quot;  has_root_directory()-: &quot; &lt;&lt; say_what(p.has_root_directory()) &lt;&lt; '\n';
1276  cout  &lt;&lt;  &quot;  has_root_path()------: &quot; &lt;&lt; say_what(p.has_root_path()) &lt;&lt; '\n';
1277  cout  &lt;&lt;  &quot;  has_relative_path()--: &quot; &lt;&lt; say_what(p.has_relative_path()) &lt;&lt; '\n';
1278  cout  &lt;&lt;  &quot;  has_parent_path()----: &quot; &lt;&lt; say_what(p.has_parent_path()) &lt;&lt; '\n';
1279  cout  &lt;&lt;  &quot;  has_filename()-------: &quot; &lt;&lt; say_what(p.has_filename()) &lt;&lt; '\n';
1280  cout  &lt;&lt;  &quot;  has_stem()-----------: &quot; &lt;&lt; say_what(p.has_stem()) &lt;&lt; '\n';
1281  cout  &lt;&lt;  &quot;  has_extension()------: &quot; &lt;&lt; say_what(p.has_extension()) &lt;&lt; '\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&amp; p);
1300uintmax_t <a name="file_size2">file_size</a>(const path&amp; p, system::error_code&amp; 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&amp;</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>&copy; 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