Every Flavour Beans

“The time has come…to talk of many [technologies].” –Lewis Carroll(’The Walrus and the Carpenter’)
Development Tools. Web Frameworks. GNU/Linux. Nokia N800. Video Encoding.

May 10, 2006

Boost Filesystem Library: Writing Portable C++ Programs to Acess The Filesystem

Filed under: C++ Boost — tabrez @ 5:40 pm

Beyond the C++ Standard Library : An Introduction to BoostBoost Filesystem library allows us to write portable code to access files and directories from a C++ program without using the operating system specific system/library calls. I have written about the Boost family of libraries in an earlier post, and have posted the procedure to install and get started with the Boost libraries on various OS distributions here. In this post, I will be talking about one of the popular Boost libraries – the Filesystem library. Lets first consider how a C++ program that needs to check for the existence of a file might look like:

first.cpp

C++:
  1. #include<iostream>
  2. #include<sys/stat.h>
  3. #include<errno.h>
  4.  
  5. int main()
  6. {
  7.     struct stat st;
  8.     if(lstat(“first.cpp”, &st) == -1 && errno == ENOENT)
  9.         std::cout<<"the file doesn't exist.\n";
  10.     else
  11.         std::cout<<"the file exists.\n";
  12. }

The above code runs under most of the GNU/Linux operating systems. It won't work under the Windows operating system though. One way to write portable code that runs under different operating systems without needing any modifications, is to use #ifdef family of preprocessor directives that selectively include different parts of the code on different operating systems. A better way would be to create an intermediate abstraction layer that provides a single interface to the programs to talk to different operating systems. Boost provides one such interface, with implementations available for Windows and all POSIX compatible operating systems, which covers most of the popular operating systems today. Additional benefits of using the Boost libraries are robustness and the design practices that are close to philosophy of the C++ standard library itself. Let's try to write the above program using the Boost Filesystem library:

first.cpp

C++:
  1. #include<boost/filesystem/operations.hpp>
  2. #include<iostream>
  3.  
  4. namespace bf = boost::filesystem;         //create an alias
  5.  
  6. int main()
  7. {
  8.     bf::path p("first.cpp");
  9.     if(bf::exists(p))
  10.         std::cout<<p.leaf()<<" exists.\n";
  11.     else
  12.         std::cout<<p.leaf()<<" does not exist.\n";
  13. }

Line 4 above creates an alias named 'bf' to the namespace 'boost::filesystem' which contains all the functions useful for the manipulation of files(like exists(), is_directory(), etc). 'path' is a type that allows paths to be represented in a platform independent format; instead of passing path names as strings to every boost function, we just wrap it in a 'path' object and use the object in its place.

C++:
  1. bf::path p("first.cpp");       //'p' represents "first.cpp"

C++ Template Metaprogramming : Concepts, Tools, and Techniques from Boost and Beyond (C++ in Depth Series)

The function exists() takes a path name as its argument(i.e, an object of type 'path') and returns true if the path represented by the path name exists; otherwise false. We print the return value of the function 'leaf()', which is the last part of the path stored in p; so for example if "/home/user/tests/first.cpp" is stored in the path object, then invoking leaf() on it will return 'first.cpp'.

The exact procedure to compile the above program depends on the specific platform used(compilation on some platforms discussed here), but it should be on the similar lines to :

sh# g++ -Wall -o first first.cpp -lboost_filesystem

Similarly, there are a bunch of other operations that can be performed on the underlying file system using the boost filesystem library, and all of these are declared in the 'operations.hpp' header file. The class 'path' itself is defined in the 'path.hpp' header file, but we do not need to include it separately as it is already included by the 'operations.hpp' file. Some of the other interesting functions available in boost filesystem library are demonstrated by the following example:

second.cpp

C++:
  1. #include<boost/filesystem/operations.hpp>
  2. #include<iostream>
  3.  
  4. namespace bf = boost::filesystem;
  5.  
  6. int main()
  7. {
  8.     bf::path p("second.cpp");
  9.     if( !bf::exists(p) )
  10.     {
  11.         std::cout<<p.leaf()<<" exists.\n";
  12.       return -1;
  13.     }
  14.     if( bf::is_directory(p) )
  15.         std::cout<<p.leaf()<<" is a directory.\n";
  16.     else if( bf::symbolic_link_exists(p) )
  17.         std::cout<<p.leaf()<<" is a symbolic link.\n";
  18.     else
  19.         std::cout<<p.leaf()<<" is a regular file.\n";
  20.  
  21.     std::cout<<"file size: "<<bf::file_size(p)<<"\n";
  22.     std::cout<<"last modification time: "<<bf::last_write_time(p);
  23.     std::cout<<std::endl;
  24. }

The program should be self-explanatory. There are a lot of other functions that allow operations like: creation and deletion of files, iterating over all the files present in a directory, copying and moving files between directories, etc. I would follow-up with examples that use these operations, but until then the following links should keep you busy:
Boost Filesystem
operations.hpp header file


If you want to receive future posts by email, enter your email address here:

Related Posts:

  • C++ Boost Filesystem Library(Part III): Example Programs
  • C++ Boost Filesystem Library(Part II): Example Programs
  • Setting the Stage for C++ Boost
  • How to Test C++ Boost Installation
  • Installing C++ Boost on Gentoo and Debian/Ubuntu
  • Installing C++ Boost on Microsoft Windows for Visual Studio .NET 2003/2005/Orcas
  • Installing C++ Boost on SuSE and Fedora

  • 2 Comments »

    1. [...] Continuing from where I had left in my earlier post containing the basics of the C++ Boost Filesystem Library, below are some example programs that make use of some common facilities available in the Boost Filesystem Library. I assume that all the code snippets shown in this post are properly nested within the main() function apart from including the following things: Show Plain Text C++: [...]

      Quote

      Pingback by Every Flavour Beans » C++ Boost Filesystem Library(Part II): Example Programs — May 28, 2006 @ 7:59 pm

    2. Just a note on your second.cpp , im not sure that you can assume this at line 18-19:

      //-------------
      else
      std::cout<<p.leaf()<<" is a regular file.\n";
      //-------------

      here is a modified snippet from a project I am currently working on:

      namespace fs = boost::filesystem;
      void filetype_handler::classify(fs::path mypath){
      try{
      if (fs::is_directory(mypath)){ //is it a directory
      std::cerr << mypath << " is a directory" << std::endl;
      }
      else if (fs::is_regular(mypath)){ //is it a regular file
      std::cerr << mypath << " is a regular file" << std::endl;
      }
      else if (fs::is_symlink(mypath)){ //is it a symbolic link?
      std::cerr << mypath << " is a symlink" << std::endl;
      }
      else if (fs::is_other(mypath)){ //its something else...
      std::cerr << mypath << " is an unknown filesystem entity" << std::endl;
      }
      else{} // should theoretically be equivalent to fs::is_other() branch above.
      }catch(fs::basic_filesystem_error e){
      std::cerr << "Cannot read path \"" << mypath << "\" : "<< e.what() <<"\n";
      }
      }

      Quote

      Comment by Preet Kukreti — February 2, 2008 @ 2:37 pm

    RSS feed for comments on this post. TrackBack URI

    Leave a comment

    Subscribe without commenting


    Copyright (c) 2006, 2007 Tabrez Iqbal.
    Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. Verbatim copying and distribution of this entire article is permitted in any medium without royalty provided this notice is preserved. A copy of the license is included in the section entitled "GNU Free Documentation License".


    Powered by WordPress
    This website is hosted by Dreamhost