我在第二次调用时打开同一目录时遇到问题。 例如我首先打开folder1 / folder2;然后,如果我调用我在folder1上使用的函数,它说它无法打开它。我虽然会关闭路径中的所有目录并试图这样做,但没有结果。 这是我的代码
void scanDir(char *dir, int depth, char type, char *path, long gtsize, int attrib)
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
char newPath[strlen(path)+strlen(dir)];
if((dp = opendir(dir)) == NULL) {
fprintf(stderr,"Cannot open directory %s\n because of e", dir);
exit(10);
return;
}
strcpy(newPath, path);
strcat(newPath, dir);
if (type!='f' && testAttrib(attrib, dir))
printf("%s\n", newPath);
strcat(newPath, "/");
chdir(dir);
while((entry = readdir(dp)) != NULL) {
stat(entry->d_name,&statbuf);
if(S_ISDIR(statbuf.st_mode) && testAttrib(attrib, entry->d_name)) {
if(!strcmp(".",entry->d_name) || !strcmp("..",entry->d_name))
continue; // ignore . and ..
if (depth>1 || depth<=-1)
scanDir(entry->d_name,depth-1,type,newPath,gtsize,attrib);
}
if(S_ISREG(statbuf.st_mode) && type!='d' && testAttrib(attrib, entry->d_name)) {
off_t sizeF = statbuf.st_size;
char filePath[100];
strcpy(filePath, newPath);
strcat(filePath, entry->d_name);
if(sizeF>=gtsize)
printf("%s \n", filePath);
}
}
chdir("..");
closedir(dp);
}
答案 0 :(得分:2)
char newPath[strlen(path)+strlen(dir)]; //WRONG!
肯定是错的。您需要为终止0保留一个额外字节,并且您要添加/
。所以它应该是
char newPath[strlen(path)+strlen(dir)+2];
顺便说一句,请考虑使用snprintf(3)或asprintf(3)代替strcat
来电。
我不确定调用chdir(2)是一个明智的想法,你当然应该检查它是否顺利。请参阅perror(3),errno(3),strerror(3)。
同时查看nftw(3)。
答案 1 :(得分:1)
在struct dirent中,成员d_name包含没有路径的名称。这意味着传递给函数opendir()的参数没有文件或目录的路径,因此发生错误ENOENT。
假设你有目录/ home / usr / folder1 / folder2。你打电话给
scandir("/home/usr/folder1/", 2, type, ...) // I understood only first two parameters.
这个函数似乎有效,但是当函数递归调用自己搜索/ home / usr / folder1 / folder2时
if (depth>1 || depth<=-1)
scanDir(entry->d_name,depth-1,type,newPath,gtsize,attrib);
这次传递给scandir的第一个参数是&#34; folder2&#34;不是&#34; / home / usr / folder1 / folder2&#34;所以opendir(dir)给出了一个名为ENOENT的错误
还有一点需要注意的是readdir()函数不是可重入函数,因此调用readdir()函数可能会导致预期的错误。在你的代码中,它看起来像函数提供你想要的结果。但是,我认为&#34;它如何运作&#34;可能与你的想法不同。如果代码变得复杂,我建议使用readdir_r()函数,它是readdir的重入版本
根据readdir的手册页:
递归调用scandir()函数后,在每个函数堆栈中,由于结构是静态分配的,因此您的条目变为NUll指针。成功时,readdir()返回指向dirent结构的指针。 (这个 结构可以静态分配;不要试图释放(3)它。)
对你的功能的另一个建议是使用linux提供的nftw()或scandir()函数。特别是nftw非常强大,而你们大多数人都想要。