Boost Filesystem Library: Writing Portable C++ Programs to Acess The Filesystem
Boost 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
[cpp]
#include
#include
#include
int main()
{
struct stat st;
if(lstat(“first.cppâ€, &st) == -1 && errno == ENOENT)
std::cout<<"the file doesn't exist.\n";
else
std::cout<<"the file exists.\n";
}
[/cpp]
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
[cpp]
#include
#include
namespace bf = boost::filesystem; //create an alias
int main()
{
bf::path p(“first.cpp”);
if(bf::exists(p))
std::cout<
std::cout<
[/cpp]
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.
[cpp]
bf::path p(“first.cpp”); //’p’ represents “first.cpp”
[/cpp]
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 :
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
[cpp]
#include
#include
namespace bf = boost::filesystem;
int main()
{
bf::path p(“second.cpp”);
if( !bf::exists(p) )
{
std::cout<
}
if( bf::is_directory(p) )
std::cout<
std::cout<
std::cout<
std::cout<<"file size: "<
[/cpp]
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

[...] 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++: [...]
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”;
}
}
i need solution for the below question plz
consider 8X8 matrix. which has 0-15 elements, less than 0 , greater then 15. the elements will be stored in a different file.and the out put should be produced in different file. output should contain the elements only less than 0 and greater than 15 including which row and column ie location of the element?
Question: is this
if( !bf::exists(p) )
{
std::cout<<p.leaf()<<” exists.\n”;
return -1;
}
intentional?
Nope, that was wrongly copy/pasted from the earlier example I guess. Thanks for pointing it out, I have corrected the print message.