1

I have a problem with getting the latest file of a directory. My code works just fine unless there is only one file in that folder. I am using the CFileFind class to make this all happened. I looked at the Microsoft documentation and it says that .GetFileName can only be called after FindNextFile. If anybody has a solution I would be very thankful. Here is my code:

std::string getLatestFile(std::string directory, const std::string& extension) {
        FILETIME mostRecent = { 0, 0 };
        FILETIME curDate;
        std::string name;
        CFileFind finder;
        if (!CheckIfDirectory(directory))
            return "";
        ensureProperTermination(directory);//this just makes sure that the path is "\\" terminated
        if (extension[0] == '.')
            finder.FindFile((directory + "*" + extension).c_str());
        else
            finder.FindFile((directory + "*." + extension).c_str());

        while (finder.FindNextFile())
        {
            finder.GetCreationTime(&curDate);

            if (CompareFileTime(&curDate, &mostRecent) > 0)
            {
                mostRecent = curDate;
                name = finder.GetFileName().GetString();
            }
        }
        return directory + name;
    }
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
V Mircan
  • 203
  • 5
  • 13
  • 1
    Unrelated to your issue, but you will want to use Unicode instead of ANSI encoding. File names are outside your control, and you *will* come across files with names, that cannot be represented in a single code page. Use `std::wstring` or `CStringW`. – IInspectable Jul 26 '18 at 09:21

1 Answers1

2

Do it like this:

void GetAllFilesNames(const CString& sMask, CStringArray& files)
{
    CFileFind finder;
    BOOL bWorking = finder.FindFile(sMask);
    while (bWorking)
    {
        bWorking = finder.FindNextFile();

        // skip . and .. files
        if (!finder.IsDots())
        {
            files.Add(finder.GetFileName());
        }
    }

}

So the call will look like this:

CStringArray Files;
GetAllFilesNames(_T("C:\\Test\\*.txt"), Files);

In your case it is going to look like this:

CString GetMostRecent(const CString& sMask)
{    
    CFileFind finder;
    BOOL bWorking = finder.FindFile(sMask);
    CTime dt;
    CString sMostRecent;
    while (bWorking)
    {
        bWorking = finder.FindNextFile();

        // skip . and .. files
        if (!finder.IsDots())
        {
            CTime lw;
            finder.GetLastWriteTime(lw);

            if (lw > dt)
            {
                dt = lw;
                sMostRecent = finder.GetFileName();
            }

        }
    }

    return sMostRecent;

}

Andrew Komiagin
  • 6,446
  • 1
  • 13
  • 23