I am trying to get filenames in a directory "in order". I tried with c++ std::filesystem::directory_iterator to do so. As mentioned in https://en.cppreference.com/w/cpp/filesystem/directory_iterator it provides all filenames in the directory, excluding "." and ".." operator but not in order.
Kindly do help me out, Thanks in advance.
Here is the simple code i used
#include <iostream>
#include <string>
#include <experimental/filesystem>
#include <vector>
int main
{
// path to cereal folder
std::string path_to_cereal_folder = "/home/ros2/Documents";
for (auto& entry : std::experimental::filesystem::directory_iterator(path_to_cereal_folder) )
{
std::cout << entry.path() << std::endl;
}
return 0;
}
You can use opendir / readdir / closedir. Sample code which searches a directory for entry ``name'' is: len = strlen(name); dirp = opendir("."); while ((dp = readdir(dirp)) !=
boost::filesystem::path is the central class in Boost. Filesystem for representing and processing paths. Definitions can be found in the namespace boost::filesystem and in the header file boost/filesystem. hpp . Paths can be built by passing a string to the constructor of boost::filesystem::path (see Example 35.1).
The Boost Filesystem Library provides portable facilities to query and manipulate paths, files, and directories. The motivation for the library is the need to be able to perform portable script-like operations from within C++ programs.
(since C++17) directory_iterator is a LegacyInputIterator that iterates over the directory_entry elements of a directory (but does not visit the subdirectories). The iteration order is unspecified, except that each directory entry is visited only once. The special pathnames dot and dot-dot are skipped.
As the reference states out, the iterator has no order. If you want to print the files in some order, you have to use other containers.
Steps to take:
set
set
and print out the filenames.
The entries in the set are sorted automatically.I adapted your code and came to this solution:
#include <iostream>
#include <filesystem>
#include <set>
//--------------------------------------------------------------------------//
using namespace std;
namespace fs = std::filesystem;
//--------------------------------------------------------------------------//
int main() {
string path_name = "/bin";
//--- filenames are unique so we can use a set
set<fs::path> sorted_by_name;
for (auto &entry : fs::directory_iterator(path_name))
sorted_by_name.insert(entry.path());
//--- print the files sorted by filename
for (auto &filename : sorted_by_name)
cout << filename.c_str() << endl;
}
Steps to take:
map
and print out the filenames and the timestamp converted into something useful.The helper function to convert the timestamp into a readable time was taken from here.
#include <iostream>
#include <filesystem>
#include <chrono>
#include <map>
//--------------------------------------------------------------------------//
using namespace std;
//--------------------------------------------------------------------------//
//--- helper function convert timepoint to usable timestamp
template <typename TP>
time_t to_time_t(TP tp) {
using namespace chrono;
auto sctp = time_point_cast<system_clock::duration>(tp - TP::clock::now() + system_clock::now());
return system_clock::to_time_t(sctp);
}
//--------------------------------------------------------------------------//
namespace fs = std::filesystem;
int main()
{
string path_name = "/bin";
map<time_t, fs::directory_entry> sort_by_time;
//--- sort the files in the map by time
for (auto &entry : fs::directory_iterator(path_name))
if (entry.is_regular_file()) {
auto time = to_time_t(entry.last_write_time());
sort_by_time[time] = entry;
}
//--- print the files sorted by time
for (auto const &[time, entry] : sort_by_time) {
string timestamp = asctime(std::localtime(&time));
timestamp.pop_back(); // remove automatic linebreak
cout << timestamp << "\t " << entry.path().c_str() << endl;
}
}
Steps to take:
map
and print out the filenames and the filesize converted into something useful.The helper function to convert the filesize into a readable information was taken from the cpp-reference.
#include <iostream>
#include <filesystem>
#include <map>
#include <cmath>
//--------------------------------------------------------------------------//
using namespace std;
namespace fs = std::filesystem;
//--------------------------------------------------------------------------//
//--- helper function convert the filesize into something meaningful
struct HumanReadable { uintmax_t size {}; };
template <typename Os> Os& operator<< (Os& os, HumanReadable hr) {
int i{};
double mantissa = hr.size;
for (; mantissa >= 1024.; ++i) {
mantissa /= 1024.;
}
mantissa = std::ceil(mantissa * 10.) / 10.;
os << mantissa << "BKMGTPE"[i];
return i == 0 ? os : os << "B (" << hr.size << ')';
}
//--------------------------------------------------------------------------//
int main() {
string path_name = "/bin";
map<uintmax_t, fs::directory_entry> sort_by_size;
//--- sort the files in the map by size
for (auto &entry : fs::directory_iterator(path_name))
if (entry.is_regular_file()) {
auto size = entry.file_size();
sort_by_size[size] = entry;
}
//--- print the files sorted by size
for (auto const &[size, entry] : sort_by_size)
cout << HumanReadable{size} << "\t " << entry.path().c_str() << endl;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With