The following code creates a recursive backup of a directory in the form of interlinked HTML files, structured in the same form as the input directory. It does not take the backup of the contents of a directory, just stores the names and sizes of all the files and folders contained in the directory. (It can be thought of as a hyperlinked version of [the dir /s][1] or [tree /f][2] commands.) For more details (including an example), refer to [this][3]. I cannot use C++ 14. #include <iostream> #include <sstream> #include <fstream> #include <string> #include <cassert> #include <vector> #include <cstdlib> #include <boost/filesystem.hpp> using namespace std; using namespace boost::filesystem; const path LogFileName = "DirectorySnapshotLog.txt"; ofstream Log; stringstream LogErrorStream; // Buffer soft errors to output them separately after the informational messages in the log file. // Convert any type to its string representation template<typename T> std::string ToString( const T obj ) { std::stringstream ss; ss << obj; return ss.str(); } // Convert the input size ( in bytes ) to its nearest units in the ratio of 1024. // ( Trying to do how Windows reports size of a file on right clicking and checking its properties ) string RoundSize( const long long& size ) { double ret = ( double )size; vector<string> units; units.push_back( "bytes" ); units.push_back( "KB" ); units.push_back( "MB" ); units.push_back( "GB" ); units.push_back( "TB" ); const unsigned ratio = 1024; unsigned i = 0; while ( ret > ratio && i < units.size() - 1 ) { ret /= ratio; i++; } return ToString( ret ) + " " + units[i]; } // Iterate through a directory and store everything found ( regular files, directories or any other special files ) in the input container void DirectoryIterate( const path& dirPath, vector<path>& dirContents ) { if ( exists( dirPath ) && is_directory( dirPath ) ) { copy( directory_iterator( dirPath ), directory_iterator(), back_inserter( dirContents ) ); } } // Create a set of HTML files containing information about source directory's contents and store it in the destination directory, in a directory structure similar to the source directory // Returns the total size of the source directory long long Snapshot( const path& sourcePath, const path& destinationPath ) { Log << sourcePath << endl; long long sourcePathSize = 0; // Total size of the source directory vector<path> dirContents, files, directories; try { DirectoryIterate( sourcePath, dirContents ); } catch ( const filesystem_error& ex ) { LogErrorStream << ex.what() << endl; return 0; } sort( dirContents.begin(), dirContents.end() ); // sort, since directory iteration is not ordered on some file systems for ( const auto& item : dirContents ) { if ( is_directory( item ) ) { directories.push_back( item ); } else { files.push_back( item ); } } path pwd = destinationPath / sourcePath.filename(); // Present working directory try { create_directory( pwd ); } catch ( const filesystem_error& ex ) { LogErrorStream << ex.what() << endl; return 0; } // Write the HTML file header. const path outFilePath = ( pwd / sourcePath.filename() ).string() + ".html"; ofstream outFile( outFilePath.string() ); if ( !outFile ) { LogErrorStream << "Error creating " << absolute( outFilePath ) << " : " << strerror( errno ) << endl; return 0; } outFile << "<!DOCTYPE html>\n"; outFile << "<meta charset=\"UTF-8\">\n"; outFile << "<html>\n"; outFile << "<title>" << sourcePath.filename() << "</title>\n"; outFile << "<body>\n"; // Write information about the files outFile << "<h1> Files </h1>\n"; for ( const auto& file : files ) { auto size = file_size( file ); outFile << file.filename() << "----" << RoundSize( size ) << "<br>\n"; sourcePathSize += size; } // Write information about the directories outFile << "<h1> Directories </h1>\n"; for ( const auto& directory : directories ) { long long size = Snapshot( sourcePath / directory.filename(), pwd ); sourcePathSize += size; outFile << "<a href=\"" << ( directory.filename() / directory.filename() ).generic_string() << ".html\">" << directory.filename() << "</a>----" << RoundSize( size ) << "<br>\n"; } // Write the footer outFile << "<br>\n"; outFile << "<h3>Total directory size = " << RoundSize( sourcePathSize ) << "</h3><br>\n"; outFile << "</body>\n"; outFile << "</html>\n"; return sourcePathSize; } int main() { string sourcePath, destinationPath; cout << "Enter source directory path -:\n"; getline( cin, sourcePath ); if ( !is_directory( sourcePath ) ) { cout << absolute( sourcePath ) << " is not a directory !\n"; return -1; } cout << "Enter destination directory path -:\n"; getline( cin, destinationPath ); if ( !is_directory( destinationPath ) ) { cout << absolute( destinationPath ) << " is not a directory !\n"; return -1; } cout << "\n"; Log.open( LogFileName.string() ); if ( !Log ) { cerr << "Error creating " << absolute( LogFileName ) << " : " << strerror( errno ) << endl; } Snapshot( sourcePath, destinationPath ); if ( Log ) { if ( LogErrorStream.str().empty() ) { cout << "The program ran without any errors.\n"; } else { Log << "\nERRORS -:\n\n" << LogErrorStream.str() << endl; cout << "There were some errors during the execution of this program !\n\nCheck " << absolute( LogFileName ) << " for details.\n"; } } } [1]:https://technet.microsoft.com/en-in/library/cc755121.aspx [2]:https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/tree.mspx?mfr=true [3]:https://github.com/jaggi1234/Directory-Snapshot