Une note sur la façon de naviguer dans la hiérarchie de fichiers à l'aide de fts.
Créez un exemple de programme qui analyse le répertoire donné par l'argument et affiche la taille et le chemin.
sample.cpp
#include <cstdio>
#include <fts.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
if (argc != 2) {
std::fprintf(stderr, "Usage: %s <dir>\n", argv[0]);
return -1;
}
char* const paths[] = {argv[1], nullptr};
FTS* fts = fts_open(paths, 0, nullptr);
if (fts == nullptr) {
std::fprintf(stderr, "open failed.\n");
return -1;
}
FTSENT* ent = nullptr;
while ((ent = fts_read(fts)) != nullptr) {
std::printf("%-5lu %s\n", ent->fts_statp->st_size, ent->fts_path);
}
if (fts_close(fts) != 0) {
std::fprintf(stderr, "close failed.\n");
return -1;
}
return 0;
}
Le chemin de taille du répertoire et du fichier peut être généré de manière récursive.
$ g++ -std=c++14 sample.cpp -o sample
$ ./sample testdir
4096 testdir
4096 testdir/subdir
114 testdir/subdir/fff.txt
110 testdir/subdir/eee.txt
49 testdir/subdir/ddd.txt
4096 testdir/subdir
64 testdir/bbb.txt
48 testdir/aaa.txt
8 testdir/ccc.txt
4096 testdir
Il semble possible de changer l'ordre de parcours de la hiérarchie des fichiers en donnant à fts_open un pointeur de fonction.
$ man fts
...
FTS *fts_open(char * const *path_argv, int options,
int (*compar)(const FTSENT **, const FTSENT **));
...
The argument compar() specifies a user-defined function which may be used to order the traversal of the hierarchy.
It takes two pointers to pointers to FTSENT structures as arguments and should return a negative value, zero, or a positive value to indicate if the file referenced by its first argument comes before, in any order with respect to, or after, the file referenced by its second argument.
...
Donc, modifiez-le pour donner un pointeur de fonction afin que la taille soit sortie dans l'ordre croissant, et exécutez-le à nouveau.
sample2.cpp
#include <cstdio>
#include <fts.h>
#include <sys/stat.h>
static int compar(const FTSENT** rhs, const FTSENT** lhs)
{
const FTSENT* r = *rhs;
const FTSENT* l = *lhs;
return (r->fts_statp->st_size - l->fts_statp->st_size);
}
int main(int argc, char** argv)
{
if (argc != 2) {
std::fprintf(stderr, "Usage: %s <dir>\n", argv[0]);
return -1;
}
char* const paths[] = {argv[1], nullptr};
FTS* fts = fts_open(paths, 0, compar);
if (fts == nullptr) {
std::fprintf(stderr, "open failed.\n");
return -1;
}
FTSENT* ent = nullptr;
while ((ent = fts_read(fts)) != nullptr) {
std::printf("%-5lu %s\n", ent->fts_statp->st_size, ent->fts_path);
}
if (fts_close(fts) != 0) {
std::fprintf(stderr, "close failed.\n");
return -1;
}
return 0;
}
Les fichiers du répertoire sont maintenant sortis par ordre croissant de taille.
$ g++ -std=c++14 sample2.cpp -o sample2
$ ./sample2 testdir/
4096 testdir/
8 testdir/ccc.txt
48 testdir/aaa.txt
64 testdir/bbb.txt
4096 testdir/subdir
49 testdir/subdir/ddd.txt
110 testdir/subdir/eee.txt
114 testdir/subdir/fff.txt
4096 testdir/subdir
4096 testdir/
Recommended Posts