How to read filename of the last modified file in a directory?

3.4k Views Asked by At

I have a directory with some files of different type extension. Among them, there are .grb2 files (meteo data). For instance:

...

20140729_0000_000.grb2

20140729_1200_000.grb2

20140730_1200_000.grb2

...

The thing is that I would like to read with C++ the last modified file of only this type (.grb2). Since they are named by the date, it would be also valid to read the file with the biggest number in its filename, since that is the most updated meteo data. I am currently reading it manually (entering its filename directly in C++), which is obviously not optimal since I download a lot of these files.

Have you any idea? By the way, I'm working in Windows (if it is of any help).

2

There are 2 best solutions below

0
On BEST ANSWER

You could consider using Boost Filesystem. Boost Filesystem implements the upcoming standard library specification for this.

You can use it to write more robust code and be platform independent at the same time:

Live On Coliru

for (auto&& entry : boost::make_iterator_range(fs::directory_iterator("."), {})) {
    fs::path p = entry.path();
    if (is_regular_file(p) && p.extension() == ".grb2") 
    {
        std::time_t timestamp = fs::last_write_time(p);
        if (timestamp > latest_tm) {
            latest = p;
            latest_tm = timestamp;
        }
    }
}

Although this code wasn't written in Notepad ¹, it is tested:

/tmp$ mkdir q
/tmp$ cd q
/tmp/q$ touch {a..z}.grb2
/tmp/q$ ../test

Reports:

Last modified: "./z.grb2"

/tmp/q$ touch k.grb2
/tmp/q$ ../test

Reports:

Last modified: "./k.grb2"

¹ Full disclosure: It was written in Vim on Ubuntu Linux

1
On

You should list all files, get their last modified time and compare them. Here is my code:

#include <windows.h>
#include <stdio.h>

int main()
{
    WIN32_FIND_DATAW ffd;
    wchar_t const* directory = L"D:\\My_GRB_Files\\";
    wchar_t currentFile[MAX_PATH], lastModifiedFilename[MAX_PATH];
    FILETIME currentModifiedTime, lastModified;
    HANDLE hFile;
    bool first_file = true;

    HANDLE hFind = FindFirstFileW( L"D:\\My_GRB_Files\\*.grb2", &ffd );

    if ( INVALID_HANDLE_VALUE == hFind )
    {
        return 255;
    }

    do
    {
        if ( !( ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
        {
            wcscpy( currentFile, directory );
            wcscat( currentFile, ffd.cFileName );
            // open file to read it's last modified time
            hFile = CreateFileW( currentFile, GENERIC_READ, FILE_SHARE_READ, NULL,
                    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
            if( INVALID_HANDLE_VALUE != hFile )
            {
                // get it's last write time
                if( GetFileTime( hFile, NULL, NULL, &currentModifiedTime ) != 0 )
                {
                    if( first_file )
                    {
                        lastModified = currentModifiedTime;
                        wcscpy( lastModifiedFilename, ffd.cFileName );
                        first_file = false;
                    }
                    else
                    {
                        // First file time is earlier than second file time.
                        if( CompareFileTime( &lastModified, &currentModifiedTime ) == -1 )
                        {
                            lastModified = currentModifiedTime;
                            wcscpy( lastModifiedFilename, ffd.cFileName );
                        }
                    }
                }
                CloseHandle( hFile );
            }
        }
    }
    while ( FindNextFileW( hFind, &ffd ) != 0 );

    FindClose( hFind );

    wprintf( L"Last modified file is: %s%s", directory, lastModifiedFilename );
}

I was in mood, so I coded this function for you. I hope this will help you and other people that will visit this page in future. I coded it in notepad, so sorry if there is error. Good luck.