C++ c+中的递归文件夹扫描+;

C++ c+中的递归文件夹扫描+;,c++,linux,directory,embedded,C++,Linux,Directory,Embedded,我想扫描目录树并列出每个目录中的所有文件和文件夹。我创建了一个从网络摄像机下载图像并保存在本地的程序。该程序根据图片下载的时间创建文件树。我现在想扫描这些文件夹并将图像上传到Web服务器,但我不确定如何扫描目录以找到图像。 如果有人能发布一些示例代码,那将非常有帮助 编辑:我在嵌入式linux系统上运行此程序,不想使用boostboost.Filesystem允许您这样做。看看这本书 编辑: 如果您使用的是Linux,而不想使用Boost,则必须使用Linux本机C函数。显示了许多关于如何做到这

我想扫描目录树并列出每个目录中的所有文件和文件夹。我创建了一个从网络摄像机下载图像并保存在本地的程序。该程序根据图片下载的时间创建文件树。我现在想扫描这些文件夹并将图像上传到Web服务器,但我不确定如何扫描目录以找到图像。 如果有人能发布一些示例代码,那将非常有帮助


编辑:我在嵌入式linux系统上运行此程序,不想使用boost

boost.Filesystem允许您这样做。看看这本书

编辑:

如果您使用的是Linux,而不想使用Boost,则必须使用Linux本机C函数。显示了许多关于如何做到这一点的示例。

我认为如果您可以使用Qt/Embedded,那么有QDir和QFileInfo类
可以帮助您,但这取决于您是否可以使用Qt。问题是您的系统提供了哪种API。

您需要使用dirent.h中声明的目录函数。这将描述它们,并包括示例代码。对于您的应用程序,一旦确定了目录,您将需要再次递归调用处理函数来处理目录内容。

您也可以使用glob/globfree。

有关简单的“文件树漫游”的信息,请参阅。我在这个例子中也使用了

#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);
}
同样,它既不是编译测试,也不是运行测试,但我想我应该提到它。

我是老派,没有ftw()!这很粗糙(我已经有一段时间没有直接编写C语言了),很多东西都是硬编码的,我可能把strnc*()函数的长度计算搞砸了,但你明白了。顺便说一句,K&R公司也有类似的例子

#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;
}
#包括
#包括
#包括
#包括
#包括
void listdir(char*dirname,int lvl);
int main(int argc,字符**argv)
{
如果(argc!=2){
fprintf(标准“不正确的用法!\n”);
出口(-1);
}
listdir(argv[1],0);
返回0;
}
void listdir(char*dirname,int lvl)
{
int i;
董事*d_fh;
结构方向*条目;
字符最长的_名称[4096];
while((d_fh=opendir(dirname))==NULL){
fprintf(stderr,“无法打开目录:%s\n”,dirname);
出口(-1);
}
while((entry=readdir(d_fh))!=NULL){
/*不要在树上向下移动或包含当前目录*/
如果(strncmp(条目->数据单元名称“…”,2)!=0&&
strncmp(条目->数据单元名称,“.”,1)!=0){
/*如果它是一个目录,打印它的名称并递归到其中*/
如果(条目->数据类型==DT\U目录){
对于(i=0;i<2*lvl;i++){
printf(“”);
}
printf(“%s(d)\n”,条目->d\u名称);
/*在当前目录前加前缀并递归*/
strncpy(最长的名称,dirname,4095);
strncat(最长的名称,“/”,4095);
strncat(最长的_名称,条目->d_名称,4095);
listdir(最长的_名称,lvl+1);
}
否则{
/*根据目录级别打印一些前导空格*/
对于(i=0;i<2*lvl;i++){
printf(“”);
}
printf(“%s\n”,条目->数据单元名称);
}
}
}
closedir(d_fh);
返回;
}

比自己读取目录和执行匹配更容易,但仍然不是递归的。诚然,使用GLOB_ONLYDIR意味着您可以完全避免处理dirent,但它仍然没有ftw那么方便,而且纯粹基于名称的遍历非常快速。strncmp(name,“.”,1)将排除点文件。此外,跳过(带有警告)可能比尝试使用截断的名称继续操作要好。最后,不是循环,而是一个打印缩进的可爱技巧:静态字符空间[]=”;printf(“%s”,空格[max(0,strlen(空格)-计数)];FTS的样本非常有效。我唯一需要做的更改是“ftsread”->“fts_read”,我必须将fts_read的结果转换为(FTSENT*)。我本以为在网上找到这样的代码会更容易,但这绝对是我找到的最干净的例子。谢谢fts_信息的值不是单个位。。。选项FTS_D至FTS_W定义为顺序值1至14。对于一些人来说,将代码命名为“&FTS\u F”而没有注释来解释发生了什么可能会让人感到困惑。可能有人打算在这里抢夺FTS_F、FTS_INIT、FTS_NS、FTS_NSOK、FTS_SL、FTS_slone和FTS_W。。。但富时证券或富时证券会有点奇怪。此外,我看到web上的代码执行“FTS_D”,这几乎肯定不是他们想要的(得到FTS_ERR,FTS_DEFAULT)。
#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;
}