Get the last file name from std::filesystem::directory_iterator() without iteration?
Asked Answered
L

2

6

I am trying to get the last file name. Below code does it very elegantly. But it is iterating through all the files inside the directory. Is it possible to get the last file without iteration?

#include <filesystem>
std::string latestFileName;
for (const auto &entry : fs::directory_iterator("/media/jai/Entertainment"))
      latestFileName = entry.path();
std::cout << latestFileName << std::endl;

Edited: Files in the directory is already in alphabetically increasing order. I want to pick the latest file, which is already sure to be last file in alphabetical order. As there could be million number of files, I am trying to avoid iteration.

Lavish answered 10/12, 2020 at 23:7 Comment(2)
Generally iterators are meant to be iterated. You can add numbers to a random access iterator, but you'd have to know beforehand how many files there are so you'd know what to add.Percussive
If you are just trying to get the last of an alphabetically sorted list, you can't avoid sorting. The OS doesn't necessarily store the files in any order at all, meaning that either the API you use must do the sorting or you must. std::filesystem::directory_iterator does not sort. This boost example shows how you might copy over the paths to a vector, then sort it with std::sort().Superfamily
S
3

This isn't possible, I'm afraid, but it's also not a good idea. It's a bad idea because the order of the iteration is unspecified, and you can't guarantee that the last file is the one you want. It's not possible because std::filesystem::directory_iterator appears to be implemented internally as a singly linked list.

(via cppreference.com) The iteration order is unspecified, except that each directory entry is visited only once.

So, you gain nothing of value by accessing the last path. What is your use case? There's surely a different way to accomplish what you're trying to do.

Superfamily answered 11/12, 2020 at 1:21 Comment(1)
Thanks @theOtherMichael, I edited my post to clear my aim.Lavish
L
0

As suggested by @theOtherMichael, sorting can't be avoided in case of std::filesystem::directory_iterator.

To keep it simple and fast considering my aim. I chose to do below steps:

#include <filesystem>
std::string latestFileName;

for (const auto &entry : fs::directory_iterator("/media/jai/Entertainment")){
    if (entry.path() > latestFileName)  // ASCII compare
        latestFileName = entry.path();
          
std::cout << latestFileName << std::endl;

In my case, file names are digits (e.g. 20201106_115500_0-19399776.jpg). I found string compare does the job.

Lavish answered 12/12, 2020 at 19:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.