如何使 std::filesystem::directory_iterator 按顺序列出文件名
How to make std::filesystem::directory_iterator to list filenames in order
我正在尝试获取目录 "in order" 中的文件名。我尝试使用 c++ std::filesystem::directory_iterator 来这样做。如 https://en.cppreference.com/w/cpp/filesystem/directory_iterator 中所述,它提供目录中的所有文件名,不包括“.”。和“..”运算符但不按顺序。
请帮助我,在此先感谢。
这是我使用的简单代码
#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;
}
如参考所述,迭代器没有顺序。如果要按某种顺序打印文件,则必须使用其他容器。
按字母顺序打印
要采取的步骤:
- 迭代文件并将文件名插入
set
- 迭代(排序)
set
并打印出文件名。
集合中的条目会自动排序。
我调整了你的代码并得出了这个解决方案:
#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;
}
打印按时间戳排序
要采取的步骤:
- 迭代文件并提取时间戳
- 在地图中插入文件,以其时间戳作为排序关键字
- 迭代(排序)
map
并打印出文件名和时间戳,转换成有用的东西。
将时间戳转换为可读时间的辅助函数取自 。
#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;
}
}
打印按文件大小排序
要采取的步骤:
- 迭代文件并提取文件大小
- 在地图中插入文件,以其文件大小作为排序关键字
- 迭代(排序)
map
并打印出文件名和文件大小,转换成有用的东西。
将文件大小转换为可读信息的辅助函数取自 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;
}
我正在尝试获取目录 "in order" 中的文件名。我尝试使用 c++ std::filesystem::directory_iterator 来这样做。如 https://en.cppreference.com/w/cpp/filesystem/directory_iterator 中所述,它提供目录中的所有文件名,不包括“.”。和“..”运算符但不按顺序。
请帮助我,在此先感谢。
这是我使用的简单代码
#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;
}
如参考所述,迭代器没有顺序。如果要按某种顺序打印文件,则必须使用其他容器。
按字母顺序打印
要采取的步骤:
- 迭代文件并将文件名插入
set
- 迭代(排序)
set
并打印出文件名。 集合中的条目会自动排序。
我调整了你的代码并得出了这个解决方案:
#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;
}
打印按时间戳排序
要采取的步骤:
- 迭代文件并提取时间戳
- 在地图中插入文件,以其时间戳作为排序关键字
- 迭代(排序)
map
并打印出文件名和时间戳,转换成有用的东西。
将时间戳转换为可读时间的辅助函数取自
#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;
}
}
打印按文件大小排序
要采取的步骤:
- 迭代文件并提取文件大小
- 在地图中插入文件,以其文件大小作为排序关键字
- 迭代(排序)
map
并打印出文件名和文件大小,转换成有用的东西。
将文件大小转换为可读信息的辅助函数取自 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;
}