recursive folder scanning in c++

前端 未结 6 461
小鲜肉
小鲜肉 2020-12-07 23:45

I want to scan a directory tree and list all files and folders inside each directory. I created a program that downloads images from a webcamera and saves them locally. This

相关标签:
6条回答
  • 2020-12-08 00:02

    Boost.Filesystem allows you to do that. Check out the docs!

    EDIT:
    If you are using Linux and you don't want to use Boost, you will have to use the Linux native C functions. This page shows many examples on how to do just that.

    0 讨论(0)
  • 2020-12-08 00:06

    I'm old school, no ftw() for me! This is crude (it's been a while since I did straight C programming), and lots of stuff is hardcoded, and I probably messed up my length calculations for the strnc*() functions, but you get the idea. There's a similar example in K&R btw.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include <sys/types.h>
    #include <dirent.h>
    
    void listdir(char* dirname, int lvl);
    
    int main(int argc, char** argv)
    {
    
      if (argc != 2) {
        fprintf(stderr, "Incorrect usage!\n");
        exit(-1);
      }
      listdir(argv[1], 0);
    
    
      return 0;
    }
    
    void listdir(char* dirname, int lvl)
    {
    
      int i;
      DIR* d_fh;
      struct dirent* entry;
      char longest_name[4096];
    
      while( (d_fh = opendir(dirname)) == NULL) {
        fprintf(stderr, "Couldn't open directory: %s\n", dirname);
        exit(-1);
      }
    
      while((entry=readdir(d_fh)) != NULL) {
    
        /* Don't descend up the tree or include the current directory */
        if(strncmp(entry->d_name, "..", 2) != 0 &&
           strncmp(entry->d_name, ".", 1) != 0) {
    
          /* If it's a directory print it's name and recurse into it */
          if (entry->d_type == DT_DIR) {
            for(i=0; i < 2*lvl; i++) {
              printf(" ");
            }
            printf("%s (d)\n", entry->d_name);
    
            /* Prepend the current directory and recurse */
            strncpy(longest_name, dirname, 4095);
            strncat(longest_name, "/", 4095);
            strncat(longest_name, entry->d_name, 4095);
            listdir(longest_name, lvl+1);
          }
          else {
    
            /* Print some leading space depending on the directory level */
            for(i=0; i < 2*lvl; i++) {
              printf(" ");
            }
            printf("%s\n", entry->d_name);
          }
        }
      }
    
      closedir(d_fh);
    
      return;
    }
    
    0 讨论(0)
  • 2020-12-08 00:10

    See man ftw for a simple "file tree walk". I also used fnmatch in this example.

    #include <ftw.h>
    #include <fnmatch.h>
    
    static const char *filters[] = {
        "*.jpg", "*.jpeg", "*.gif", "*.png"
    };
    
    static int callback(const char *fpath, const struct stat *sb, int typeflag) {
        /* if it's a file */
        if (typeflag == FTW_F) {
            int i;
            /* for each filter, */
            for (i = 0; i < sizeof(filters) / sizeof(filters[0]); i++) {
                /* if the filename matches the filter, */
                if (fnmatch(filters[i], fpath, FNM_CASEFOLD) == 0) {
                    /* do something */
                    printf("found image: %s\n", fpath);
                    break;
                }
            }
        }
    
        /* tell ftw to continue */
        return 0;
    }
    
    int main() {
        ftw(".", callback, 16);
    }
    

    (Not even compile-tested, but you get the idea.)

    This is much simpler than dealing with DIRENTs and recursive traversal yourself.


    For greater control over traversal, there's also fts. In this example, dot-files (files and directories with names starting with ".") are skipped, unless explicitly passed to the program as a starting point.

    #include <fts.h>
    #include <string.h>
    
    int main(int argc, char **argv) {
        char *dot[] = {".", 0};
        char **paths = argc > 1 ? argv + 1 : dot;
    
        FTS *tree = fts_open(paths, FTS_NOCHDIR, 0);
        if (!tree) {
            perror("fts_open");
            return 1;
        }
    
        FTSENT *node;
        while ((node = fts_read(tree))) {
            if (node->fts_level > 0 && node->fts_name[0] == '.')
                fts_set(tree, node, FTS_SKIP);
            else if (node->fts_info & FTS_F) {
                printf("got file named %s at depth %d, "
                    "accessible via %s from the current directory "
                    "or via %s from the original starting directory\n",
                    node->fts_name, node->fts_level,
                    node->fts_accpath, node->fts_path);
                /* if fts_open is not given FTS_NOCHDIR,
                 * fts may change the program's current working directory */
            }
        }
        if (errno) {
            perror("fts_read");
            return 1;
        }
    
        if (fts_close(tree)) {
            perror("fts_close");
            return 1;
        }
    
        return 0;
    }
    

    Again, it's neither compile-tested nor run-tested, but I thought I'd mention it.

    0 讨论(0)
  • 2020-12-08 00:14

    I think if you can use Qt/Embedded, there are QDir and QFileInfo classes which can help you, though it depends if you can use the Qt. The question is which API your system provides.

    0 讨论(0)
  • 2020-12-08 00:20

    You will want to use the directory functions declared in dirent.h. This wikipedia page describes them and includes sample code. For your application, once you have identified a directory, you will want to call the processing function again recursively to process the directory contents.

    0 讨论(0)
  • 2020-12-08 00:20

    You can also use glob/globfree.

    0 讨论(0)
提交回复
热议问题