【发布时间】:2010-11-02 06:33:45
【问题描述】:
我想扫描目录树并列出每个目录中的所有文件和文件夹。我创建了一个从网络摄像头下载图像并将其保存在本地的程序。该程序根据下载图片的时间创建一个文件树。我现在想扫描这些文件夹并将图像上传到网络服务器,但我不确定如何扫描目录以查找图像。 如果有人可以发布一些示例代码,那将非常有帮助。
编辑:我在嵌入式 linux 系统上运行它,不想使用 boost
【问题讨论】:
标签: c++ linux directory embedded
我想扫描目录树并列出每个目录中的所有文件和文件夹。我创建了一个从网络摄像头下载图像并将其保存在本地的程序。该程序根据下载图片的时间创建一个文件树。我现在想扫描这些文件夹并将图像上传到网络服务器,但我不确定如何扫描目录以查找图像。 如果有人可以发布一些示例代码,那将非常有帮助。
编辑:我在嵌入式 linux 系统上运行它,不想使用 boost
【问题讨论】:
标签: c++ linux directory embedded
请参阅man ftw 了解简单的“文件树遍历”。在这个例子中我也使用了fnmatch。
#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);
}
(甚至没有经过编译测试,但你明白了。)
这比自己处理DIRENTs和递归遍历要简单得多。
为了更好地控制遍历,还有fts。在此示例中,将跳过点文件(名称以“.”开头的文件和目录),除非明确将其作为起点传递给程序。
#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;
}
同样,它既没有经过编译测试也没有经过运行测试,但我想我会提到它。
【讨论】:
我是老派,没有 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;
}
【讨论】:
您也可以使用 glob/globfree。
【讨论】:
您将需要使用在dirent.h 中声明的目录函数。这个wikipedia page 描述了它们并包含示例代码。对于您的应用程序,一旦您确定了目录,您将需要再次递归调用处理函数来处理目录内容。
【讨论】:
我认为如果你可以使用 Qt/Embedded,有 QDir 和 QFileInfo 类 可以帮助你,虽然这取决于你是否可以使用 Qt。问题是您的系统提供了哪种 API。
【讨论】: