Skip to main content
Added an example
Source Link

As an example, this would be the output directory considering this as the input directory.

As an example, this would be the output directory considering this as the input directory.

Addded exception handling in the code
Source Link
#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 );
        }
    }

    const string sourcePathName = sourcePath.filename().string(); // Name of the source folder
    path pwd = destinationPath / sourcePathName;sourcePath.filename(); // Present working directory
    boost::system::error_code ec;
    create_directory( pwd, ec );
    if ( ec )try
    {
        LogErrorStreamcreate_directory( <<pwd "Error);
 creating " << absolute}
    catch ( pwdconst filesystem_error& ex ) 
 << " : "{
        LogErrorStream << ecex.messagewhat() << endl;
        return 0;
    }

    // Write the HTML file header.
    const path outFilePath = ( pwd / sourcePathNamesourcePath.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>" << sourcePathNamesourcePath.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 << "ERRORS"\nERRORS -:\n"\n\n" << LogErrorStream.str() << endl;
            cout << "There were some errors during the execution of this program !\n\nCheck " << absolute( LogFileName ) << " for details.\n";
        }
    }
}
#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;
    DirectoryIterate( sourcePath, dirContents );
    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 );
        }
    }

    const string sourcePathName = sourcePath.filename().string(); // Name of the source folder
    path pwd = destinationPath / sourcePathName; // Present working directory
    boost::system::error_code ec;
    create_directory( pwd, ec );
    if ( ec )
    {
        LogErrorStream << "Error creating " << absolute( pwd ) << " : " << ec.message() << endl;
        return 0;
    }

    // Write the HTML file header.
    const path outFilePath = ( pwd / sourcePathName ).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>" << sourcePathName << "</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 << "ERRORS -:\n" << LogErrorStream.str() << endl;
            cout << "There were some errors during the execution of this program !\n\nCheck " << absolute( LogFileName ) << " for details.\n";
        }
    }
}
#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";
        }
    }
}
deleted 4 characters in body
Source Link
#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.
stringstream LogErrorStream;

// 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;
    DirectoryIterate( sourcePath, dirContents );
    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 );
        }
    }

    const string sourcePathName = sourcePath.filename().string(); // Name of the source folder
    path pwd = destinationPath / sourcePathName; // Present working directory
    boost::system::error_code ec;
    create_directory( pwd, ec );
    if ( ec )
    {
        LogErrorStream << "Error creating " << absolute( pwd ) << " : " << ec.message() << endl;
        return 0;
    }

    // Write the HTML file header.
    const path outFilePath = ( pwd / sourcePathName ).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>" << sourcePathName << "</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 << "ERRORS -:\n" << LogErrorStream.str() << endl;
            cout << "There were some errors during the execution of this program !\n\nCheck " << absolute( LogFileName ) << " for details.\n";
        }
    }
}
#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;
// Buffer soft errors to output them separately after the informational messages in the log file.
stringstream LogErrorStream;

// 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;
    DirectoryIterate( sourcePath, dirContents );
    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 );
        }
    }

    const string sourcePathName = sourcePath.filename().string(); // Name of the source folder
    path pwd = destinationPath / sourcePathName; // Present working directory
    boost::system::error_code ec;
    create_directory( pwd, ec );
    if ( ec )
    {
        LogErrorStream << "Error creating " << absolute( pwd ) << " : " << ec.message() << endl;
        return 0;
    }

    // Write the HTML file header.
    const path outFilePath = ( pwd / sourcePathName ).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>" << sourcePathName << "</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 << "ERRORS -:\n" << LogErrorStream.str() << endl;
            cout << "There were some errors during the execution of this program !\n\nCheck " << absolute( LogFileName ) << " for details.\n";
        }
    }
}
#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;
    DirectoryIterate( sourcePath, dirContents );
    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 );
        }
    }

    const string sourcePathName = sourcePath.filename().string(); // Name of the source folder
    path pwd = destinationPath / sourcePathName; // Present working directory
    boost::system::error_code ec;
    create_directory( pwd, ec );
    if ( ec )
    {
        LogErrorStream << "Error creating " << absolute( pwd ) << " : " << ec.message() << endl;
        return 0;
    }

    // Write the HTML file header.
    const path outFilePath = ( pwd / sourcePathName ).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>" << sourcePathName << "</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 << "ERRORS -:\n" << LogErrorStream.str() << endl;
            cout << "There were some errors during the execution of this program !\n\nCheck " << absolute( LogFileName ) << " for details.\n";
        }
    }
}
added 14 characters in body
Source Link
Loading
deleted 8 characters in body
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237
Loading
added 14 characters in body
Source Link
Loading
added 26 characters in body
Source Link
Loading
added 25 characters in body
Source Link
Loading
Source Link
Loading