Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
C++ programs showing boost::filesystem usage contrasted with std::filesystem. Output of each program included to highlight differences/similarities.
$ diff main_boostfs.cpp main_stdfs.cpp
2c2
< File: main_boostfs.cpp
---
> File: main_stdfs.cpp
5,6c5,6
< Purpose: Program to demonstrate aspects of boost::filesystem
< NOTE: Contrast behaviour differences with output of main_stdfs.cpp
---
> Purpose: Program to demonstrate aspects of std::filesystem
> NOTE: Contrast behaviour differences with output of main_boostfs.cpp
8,11c8,10
< [clang++|g++] [-I<path to boost include folder>] \
< [-L<path to boost libs>] \
< main_boostfs.cpp -o testboost \
< -l boost_system -l boost_filesystem
---
> [clang++|g++] -std=c++17 \
> main_stdfs.cpp -o teststdfs \
> -lstdc++fs
16a16
> #include <filesystem>
18,23c18
< #ifndef BOOST_FILESYSTEM_NO_DEPRECATED
< #define BOOST_FILESYSTEM_NO_DEPRECATED
< #endif
< #include <boost/filesystem.hpp>
<
< namespace fs = boost::filesystem;
---
> namespace fs = std::filesystem;
58a54
> // NOTE: std::filesystem does not have reverse path iterators!!!
62c58
< for( auto it = decompPath.rbegin(); it != decompPath.rend(); ++it )
---
> for( auto it = decompPath.end(); it != decompPath.begin(); )
63a60
> --it;
/*
File: main_boostfs.cpp
Date: 2019Apr26
Author: Scott Furry
Purpose: Program to demonstrate aspects of boost::filesystem
NOTE: Contrast behaviour differences with output of main_stdfs.cpp
Compile:
[clang++|g++] [-I<path to boost include folder>] \
[-L<path to boost libs>] \
main_boostfs.cpp -o testboost \
-l boost_system -l boost_filesystem
*/
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#ifndef BOOST_FILESYSTEM_NO_DEPRECATED
#define BOOST_FILESYSTEM_NO_DEPRECATED
#endif
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
using namespace std;
int main(int argc, char* argv[])
{
if( argc != 2 )
{
cout << "Missing Path! Usage: " << argv[0] << " [valid file path]" << endl;
return 1;
}
try
{
fs::path testpath( fs::canonical( argv[1] ));
cout << "User provided absolute path: "
<< (fs::path(argv[1]).is_absolute() ? "True" : "False")
<< endl;
// validate path supplied by user
if( !fs::exists( testpath ))
{
cout << "Bad Path! Usage: " << argv[0] << " [valid file path]" << endl;
return 1;
}
// demonstrate by example necessity of fs::path with/without string()
// stream << fs::path --> produces "path in quotes"
// stream << fs::path::string() -> produces path not in quotes
cout << "Current working dir:" << setw(3) << ' ' << fs::current_path() << endl;
cout << "Current path seperator: " << fs::path::preferred_separator << endl;
// print out some details about this path
cout << "Root Path:" << setw(14) << ' ' << testpath.root_path().string() << endl;
cout << "Parent Path:" << setw(12) << ' ' << testpath.parent_path().string() << endl;
// iterate backwards through path for decomposition
// use output to build path - in reverse
// need to create a derived path to use filesystem path iterators
fs::path revPath;
fs::path decompPath( testpath.parent_path() );
cout << "Decomposition: " << endl;
for( auto it = decompPath.rbegin(); it != decompPath.rend(); ++it )
{
// (*it) is type fs::path
cout << setw(6) << ' ' << (*it).string() << endl;
// path append operator - separator added by library
revPath /= (*it);
}
// NOTE: output std::filesystem will be different from boost::filesystem
// problem is with append operator where appending path that starts with "/"
cout << "Reverse Path:" << setw(11) << ' ' << revPath.string() << endl;
// Dig into information about path supplied by the user
cout << "Path Filename:" << setw(10) << ' ' << testpath.filename().string() << endl;
if( fs::is_regular_file( testpath ))
{
// user gave a file name - print some more details
cout << testpath.string() << " size is " << fs::file_size(testpath) << " bytes" << endl;
cout << setw(6) << ' ' << "File Name Stem: " << testpath.stem().string() << endl;
cout << setw(6) << ' ' << "File Extension: " << testpath.extension().string() << endl;
}
else if( fs::is_directory( testpath ))
{
cout << testpath.string() << " is a directory containing:" << endl;
typedef vector<fs::path> vec; // store paths,
vec vPaths; // so we can sort them later
// STL algorithm magic to save path all at once
copy( fs::recursive_directory_iterator( testpath ),
fs::recursive_directory_iterator(),
back_inserter( vPaths ));
// sort names of directory contents - not done by filesystem
// explicitly call out using sort from std namespace
std::sort( vPaths.begin(), vPaths.end() );
for( auto& aPath : vPaths )
{
cout << setw(6) << ' ' << aPath.string() << '\n';
}
}
else
{
cout << testpath << " exists, but is neither a regular file nor a directory" << endl;
}
}
catch (const fs::filesystem_error& ex)
{
cout << ex.what() << '\n';
}
return 0;
}
/*
File: main_stdfs.cpp
Date: 2019Apr26
Author: Scott Furry
Purpose: Program to demonstrate aspects of std::filesystem
NOTE: Contrast behaviour differences with output of main_boostfs.cpp
Compile:
[clang++|g++] -std=c++17 \
main_stdfs.cpp -o teststdfs \
-lstdc++fs
*/
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <filesystem>
namespace fs = std::filesystem;
using namespace std;
int main(int argc, char* argv[])
{
if( argc != 2 )
{
cout << "Missing Path! Usage: " << argv[0] << " [valid file path]" << endl;
return 1;
}
try
{
fs::path testpath( fs::canonical( argv[1] ));
cout << "User provided absolute path: "
<< (fs::path(argv[1]).is_absolute() ? "True" : "False")
<< endl;
// validate path supplied by user
if( !fs::exists( testpath ))
{
cout << "Bad Path! Usage: " << argv[0] << " [valid file path]" << endl;
return 1;
}
// demonstrate by example necessity of fs::path with/without string()
// stream << fs::path --> produces "path in quotes"
// stream << fs::path::string() -> produces path not in quotes
cout << "Current working dir:" << setw(3) << ' ' << fs::current_path() << endl;
cout << "Current path seperator: " << fs::path::preferred_separator << endl;
// print out some details about this path
cout << "Root Path:" << setw(14) << ' ' << testpath.root_path().string() << endl;
cout << "Parent Path:" << setw(12) << ' ' << testpath.parent_path().string() << endl;
// iterate backwards through path for decomposition
// use output to build path - in reverse
// need to create a derived path to use filesystem path iterators
// NOTE: std::filesystem does not have reverse path iterators!!!
fs::path revPath;
fs::path decompPath( testpath.parent_path() );
cout << "Decomposition: " << endl;
for( auto it = decompPath.end(); it != decompPath.begin(); )
{
--it;
// (*it) is type fs::path
cout << setw(6) << ' ' << (*it).string() << endl;
// path append operator - separator added by library
revPath /= (*it);
}
// NOTE: output std::filesystem will be different from boost::filesystem
// problem is with append operator where appending path that starts with "/"
cout << "Reverse Path:" << setw(11) << ' ' << revPath.string() << endl;
// Dig into information about path supplied by the user
cout << "Path Filename:" << setw(10) << ' ' << testpath.filename().string() << endl;
if( fs::is_regular_file( testpath ))
{
// user gave a file name - print some more details
cout << testpath.string() << " size is " << fs::file_size(testpath) << " bytes" << endl;
cout << setw(6) << ' ' << "File Name Stem: " << testpath.stem().string() << endl;
cout << setw(6) << ' ' << "File Extension: " << testpath.extension().string() << endl;
}
else if( fs::is_directory( testpath ))
{
cout << testpath.string() << " is a directory containing:" << endl;
typedef vector<fs::path> vec; // store paths,
vec vPaths; // so we can sort them later
// STL algorithm magic to save path all at once
copy( fs::recursive_directory_iterator( testpath ),
fs::recursive_directory_iterator(),
back_inserter( vPaths ));
// sort names of directory contents - not done by filesystem
// explicitly call out using sort from std namespace
std::sort( vPaths.begin(), vPaths.end() );
for( auto& aPath : vPaths )
{
cout << setw(6) << ' ' << aPath.string() << '\n';
}
}
else
{
cout << testpath << " exists, but is neither a regular file nor a directory" << endl;
}
}
catch (const fs::filesystem_error& ex)
{
cout << ex.what() << '\n';
}
return 0;
}
## with directory name provided
$ ./testboostfs .
User provided absolute path: False
Current working dir: "/home/user/topic/guest_articles"
Current path seperator: /
Root Path: /
Parent Path: /home/user/topic
Decomposition:
topic
user
home
/
Reverse Path: topic/user/home/
Path Filename: guest_articles
/home/user/topic/guest_articles is a directory containing:
/home/user/topic/guest_articles/converting_from_boost_to_std_filesystem.md
/home/user/topic/guest_articles/main_boostfs.cpp
/home/user/topic/guest_articles/main_stdfs.cpp
/home/user/topic/guest_articles/testboostfs
/home/user/topic/guest_articles/teststdfs
## with file name provided
$ ./testboostfs main_boostfs.cpp
...
Parent Path: /home/user/topic/guest_articles
Decomposition:
guest_articles
topic
user
home
/
Reverse Path: guest_articles/topic/user/home/
Path Filename: main_boostfs.cpp
/home/user/topic/guest_articles/main_boostfs.cpp size is 4402 bytes
File Name Stem: main_boostfs
File Extension: .cpp
## with directory name provided
$ ./testboostfs .
User provided absolute path: False
Current working dir: "/home/user/topic/guest_articles"
Current path seperator: /
Root Path: /
Parent Path: /home/user/topic
Decomposition:
topic
user
home
/
Reverse Path: /
Path Filename: guest_articles
/home/user/topic/guest_articles is a directory containing:
/home/user/topic/guest_articles/converting_from_boost_to_std_filesystem.md
/home/user/topic/guest_articles/main_boostfs.cpp
/home/user/topic/guest_articles/main_stdfs.cpp
/home/user/topic/guest_articles/testboostfs
/home/user/topic/guest_articles/teststdfs
## with file name provided
$ ./testboostfs main_boostfs.cpp
...
Parent Path: /home/user/topic/guest_articles
Decomposition:
guest_articles
topic
user
home
/
Reverse Path: /
Path Filename: main_stdfs.cpp
/home/user/topic/guest_articles/main_stdfs.cpp size is 4300 bytes
File Name Stem: main_stdfs
File Extension: .cpp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.