Question

Given:

  • filesystem::path toDir("./");
  • ptime oldTime;
  • ptime now(second_clock::local_time());

How can I determine which files were created in the time period between oldTime and now?

The names of such "fresh" files should be streamed to cout.

Update: Well based on given answer I made a small programm:

#include <sstream>
#include <stdio.h>
#include <time.h>
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
#include <boost/timer.hpp>
#include <boost/date_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>

using namespace boost::filesystem;
using namespace boost::posix_time;
using namespace boost::local_time;
using namespace boost::gregorian;
using namespace std;

path file_service_default_path;

boost::timer timerFame;
int64_t desiredTimeFame;
int64_t spendedTimeFame;
ptime oldTime;
ptime nowTime;
bool first_time;

string file_service_get_dif_path(path base_path, path new_path)
{
    path sdiffpath;
    path stmppath = new_path;
    while(stmppath != base_path) {
        sdiffpath = path(stmppath.stem().string() + stmppath.extension().string())/ sdiffpath;
        stmppath = stmppath.parent_path();
    }
    string diff_path =sdiffpath.string();// boost::lexical_cast<string>(sdiffpath);
    diff_path = diff_path.substr(0, (diff_path.length()));
    std::replace(diff_path.begin(), diff_path.end(), '\\', '/');
    return diff_path;
}

void is_file(path p)
{
    std::string a =  file_service_get_dif_path(file_service_default_path, p);
    std::cout << "File: " <<  a << std::endl;
}

void is_new_file(path p)
{
    std::time_t t = boost::filesystem::last_write_time( p );
    ptime lastAccessTime = from_time_t( t );
    if ( lastAccessTime >= oldTime && lastAccessTime <= nowTime )
    {
        std::string a =  file_service_get_dif_path(file_service_default_path, p);
        std::cout << "File: " <<  a << " is new to us." << std::endl;
    }   
}

void is_dir(path dir)
{
    boost::filesystem::directory_iterator dirIter( dir ), dirIterEnd;
    while ( dirIter != dirIterEnd )
    {
        if ( boost::filesystem::exists( *dirIter ) && !boost::filesystem::is_directory( *dirIter ) )
        {
            if (first_time)
            {
                is_file((*dirIter));
            }
            else
            {
                is_new_file((*dirIter));
            }
        }
        else
        {
            is_dir((*dirIter));
        }
        ++dirIter;
    }
}

void files_walker()
{
    while(true)
    {
        timerFame.restart();
        oldTime = nowTime;
        nowTime = second_clock::local_time() ;
        file_service_default_path = file_service_default_path;
        is_dir(file_service_default_path);
        first_time = false;
        spendedTimeFame = (int64_t)timerFame.elapsed();
        cout << spendedTimeFame << std::endl;
        if (spendedTimeFame < desiredTimeFame)
            boost::this_thread::sleep(boost::posix_time::milliseconds(desiredTimeFame - spendedTimeFame));
    }
}

int main()
{
    desiredTimeFame = (int64_t)(5000.0f);
    first_time = true;
    file_service_default_path = "./new";
    boost::thread workerThread(files_walker);
    cin.get();
}

But it seems not to show any new files=( how to fix it?

Update 2:

Solved with nowTime = second_clock::universal_time();

Update 3: fixed code:

#include <sstream>
#include <stdio.h>
#include <time.h>
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
#include <boost/timer.hpp>
#include <boost/date_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>

using namespace boost::filesystem;
using namespace boost::posix_time;
using namespace boost::local_time;
using namespace boost::gregorian;
using namespace std;

path file_service_default_path;

boost::timer timerFame;
int64_t desiredTimeFame;
int64_t spendedTimeFame;
ptime oldTime;
ptime nowTime;
bool first_time;

string file_service_get_dif_path(path base_path, path new_path)
{
    path sdiffpath;
    path stmppath = new_path;
    while(stmppath != base_path) {
        sdiffpath = path(stmppath.stem().string() + stmppath.extension().string())/ sdiffpath;
        stmppath = stmppath.parent_path();
    }
    string diff_path =sdiffpath.string();// boost::lexical_cast<string>(sdiffpath);
    diff_path = diff_path.substr(0, (diff_path.length()));
    std::replace(diff_path.begin(), diff_path.end(), '\\', '/');
    return diff_path;
}

void is_file(path p)
{
    std::string a =  file_service_get_dif_path(file_service_default_path, p);
    std::cout << "File: " <<  a << std::endl;
}

void is_new_file(path p)
{
    std::time_t t = boost::filesystem::last_write_time( p );
    ptime lastAccessTime = from_time_t( t );
    if ( lastAccessTime >= oldTime && lastAccessTime <= nowTime )
    {
        std::string a =  file_service_get_dif_path(file_service_default_path, p);
        std::cout << "File: " <<  a << " is new to us." << std::endl;
    }   
}

void is_dir(path dir)
{
    if(!exists(dir))
    {
        return;
    }
    boost::filesystem::directory_iterator dirIter( dir );
    boost::filesystem::directory_iterator dirIterEnd;
    while ( dirIter != dirIterEnd )
    {
        if ( boost::filesystem::exists( *dirIter ) && !boost::filesystem::is_directory( *dirIter ) )
        {
            if (first_time)
            {
                is_file((*dirIter));
            }
            else
            {
                is_new_file((*dirIter));
            }
        }
        else
        {
            is_dir((*dirIter));
        }
        ++dirIter;
    }
}

void files_walker()
{
    while(true)
    {
        timerFame.restart();
        oldTime = nowTime;
        nowTime = second_clock::universal_time();
        is_dir(file_service_default_path);
        first_time = false;
        spendedTimeFame = (int64_t)timerFame.elapsed();
        cout << spendedTimeFame << std::endl;
        if (spendedTimeFame < desiredTimeFame)
            boost::this_thread::sleep(boost::posix_time::milliseconds(desiredTimeFame - spendedTimeFame));
    }
}

int main()
{
    desiredTimeFame = (int64_t)(5000.0f);
    first_time = true;
    file_service_default_path = "./new";
    boost::thread workerThread(files_walker);
    cin.get();
}
Was it helpful?

Solution

As Emile Cormier stated, you will be unable to get the file creation time in Unix. However, you can still look for 'fresh' files, depending on your definition of 'fresh', by looking at last access time. This is achieved by a call as follows:

boost::filesystem::path p( "somefile" );
std::time_t t = boost::filesystem::last_write_time( p );
boost::ptime lastAccessTime = boost::ptime::from_time_t( t );

So if you then look at the boost::filesystem::directory_iterator you are able to iterate over a directory, i.e. "./" as you state in your question, and compare lastAccessTime given in the example above with the range specified in your question.

So the way I would do this, assuming oldTime has been previously defined, is as follows:

boost::filesystem::path dir( "./" );
boost::ptime nowTime( boost::second_clock::local_time() );

boost::filesystem::directory_iterator dirIter( dir ), dirIterEnd;
while ( dirIter != dirIterEnd )
{
    if ( boost::filesystem::exists( *dirIter ) && !boost::filesystem::is_directory( *dirIter ) )
    {
        std::time_t t = boost::filesystem::last_write_time( *dirIter );
        boost::ptime lastAccessTime = boost::ptime::from_time_t( t );
        if ( lastAccessTime >= oldTime && lastAccessTime <= nowTime )
        {
            std::cout << "File meets criteria: " << (*dirIter).filename() << std::endl;
        }     
    }
    ++dirIter;
}

Hope this helps!

You could refine this by persistently storing the last time you checked the directory and/or the last list of files present in the directory when you last checked, and use this as a point of comparison instead. Without more information as to your intentions I can't provide further guidance.

Relevant docs: boost::filesystem Reference, boost::ptime Reference

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top