gpt4 book ai didi

c - 在 Linux 上递归搜索所有子目录中的文件

转载 作者:IT王子 更新时间:2023-10-29 00:38:08 24 4
gpt4 key购买 nike

我正在尝试通过所有子目录搜索作为参数给出的文件。我的代码的问题是,当它到达一个不是目录的文件时,它会以 perror("Error opening the directory\n"); 停止。

我找不到解决这个问题的方法。我尝试使用另一个 if(S_ISREG...),但它不起作用。

include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>

void check_file_existence(char *dirName,char *file){
struct stat *metadata;
char name[1000];
struct dirent *dirEntry;
struct stat bufstat;

DIR *dir;

dir = opendir(dirName);
if (dir==NULL)
{
perror("Error opening the directory\n");
exit(1);
}

while ((dirEntry = readdir(dir))!=NULL){
lstat(dirEntry->d_name,&bufstat);

if(S_ISDIR(bufstat.st_mode)){
if (strcmp(dirEntry->d_name,".")==0 || strcmp(dirEntry->d_name,"..")==0){
continue;
}
sprintf(name,"%s/%s",dirName,dirEntry->d_name);
printf("%s\n",name);
check_file_existence(name,file);
}
}

closedir(dir);
}

int main(int argc,char **argv){
if (argc!=3){
perror("Number of arguments is wrong.\n");
exit(1);
}

check_file_existence(argv[1],argv[2]);
}

最佳答案

这是您的代码,其中进行了一些简化,顺便解决了您的错误,并进行了两项改进。它现在可以通过目录树递归搜索以找到指定文件的第一次出现。

我们使用 dirEntry 结构来识别文件类型,并添加 strcmp() 来检查指定的文件。在 dirEntry 结构中使用 d_type 是识别文件类型的最简单方法,因此往往会降低错误率。

我们检查输入是否有多余的尾部斜杠。输入上的额外斜杠不会停止任何操作,但会使输出不那么清晰。

并且,为了便于调试,我们大量使用 printf() 并添加一个例程来字节转储 dirEntry 结构的内容,以帮助您在递归和循环目录和文件。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>

void debugbytes( char *s, unsigned short nlen, char dtype, char *nameptr ) {
int n;
printf( "\n%d %x ", nlen, dtype );
switch( dtype )
{
case DT_BLK:
printf( "BLK" );
break;
case DT_CHR:
printf( "CHR" );
break;
case DT_DIR:
printf( "DIR" );
break;
case DT_FIFO:
printf( "FIFO" );
break;
case DT_LNK:
printf( "LNK" );
break;
case DT_REG:
printf( "REG" );
break;
case DT_SOCK:
printf( "SOCK" );
break;
case DT_UNKNOWN:
printf( "UNKOWN" );
break;
default:
printf( "not recognized" );
}
printf( " %s :", nameptr );
for (n = 0; n < nlen; n++ ) {
printf( "%x", s[n] );
}
printf( "\n" );
}

void check_file_existence(char *dirName,char *file){

DIR *dir;

struct dirent *dirEntry;

char name[1000];

printf( "opening %s\n", dirName );

dir = opendir(dirName);
if (dir==NULL)
{
perror("Error opening the directory\n");
exit(1);
}

while ((dirEntry = readdir(dir))!=NULL){

debugbytes( (char *) dirEntry, dirEntry->d_reclen, dirEntry->d_type, dirEntry->d_name );

if ( dirEntry->d_type == DT_DIR ) {
if (strcmp(dirEntry->d_name,".")==0 || strcmp(dirEntry->d_name,"..")==0){
continue;
}
printf( "directory\n" );
sprintf(name,"%s/%s",dirName,dirEntry->d_name);
printf("\n%s\n",name);
check_file_existence(name,file);
}

else if ( dirEntry->d_type == DT_REG ) {

printf( "file %s/%s\n", dirName, (char *)dirEntry->d_name );

if ( !strcmp( dirEntry->d_name, file ) ) {
printf( "file found\n" );
break;
}
}
}

closedir(dir);
}

int main(int argc,char **argv){
char dirspec[256] = { 0 };
int n;

if (argc!=3){
perror("Number of arguments is wrong.\n");
exit(1);
}

n = strlen( argv[1] );
while( (n > 1) && argv[1][n-1] == '/' ) n--;

strncpy(dirspec, argv[1], n );

check_file_existence( dirspec, argv[2] );
}

这是一个示例输出:

$ ./temp1 gEDA/ 1206P.fp
opening gEDA
.
.
.
32 4 DIR Footprints :3b04250000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f2004466f6f747072696e7473004
directory
.
.
.
32 8 REG 1206P.fp :ffffff8084250000ffffffd0ffffffff12ffffffeb7afffffff77052200831323036502e6670054ffffffa7ffffffce8
file gEDA/Footprints/1206P.fp
file found

$

关于c - 在 Linux 上递归搜索所有子目录中的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49339844/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com