递归列出目录 [英] listing directory recursively

查看:143
本文介绍了递归列出目录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我没有正确地写这个功能。它应该递归地列出第一个参数提供的路径的内容(如ls -R),但是它会停止太久。这是代码,预期的输出和我得到的输出:

  int browseDir(const char * path,const int * options )
{
char calldir [MAXDIRLEN];
char currentdir [MAXDIRLEN];

getcwd(calldir,MAXDIRLEN);

DIR * dirstream;
struct dirent * dir_entry;
struct stat file_data;
LIST subd_list = newList();

if(path == NULL)
strcpy(currentdir,callingdir);
else
strcpy(currentdir,path);

dirstream = opendir(currentdir);
printf(Listing:%s\\\
,currentdir);
chdir(currentdir);

if(dirstream == NULL)
{
perror(Error:can not open directory\\\
);
return 0;


while((dir_entry = readdir(dirstream))!= NULL)
{
if(!ISSET_A_FLAG(* options))
{
if(dir_entry-> d_name [0] =='。')
continue;
}
if(!ISSET_S_FLAG(* options))
{
stat(dir_entry-> d_name,& file_data);
printStat(& file_data);
}
printf(%s,dir_entry-> d_name);
printf(\\\
);
if(ISSET_R_FLAG(* options)&&(dir_entry-> d_type& DT_DIR)&& strcmp(dir_entry-> d_name,。)&& strcmp(dir_entry-> ; d_name,..))
addNode(subd_list,dir_entry-> d_name);
}
closedir(dirstream);

while(!isEmpty(subd_list))
{
browseDir((* subd_list) - >数据,选项);
delNode(subd_list);
}

chdir(calldir);
return 0;
}

使用ls -Rli(预期)输出

  tod @ iTod:〜/ Dropbox / programming / SO / myshell2 $ ls -lRi / home / tod / programming / shelldeb 
/ home / tod /编程/ shelldeb:
totale 52
1150597 drwxr-xr-x 3 tod tod 4096 ott 18 02:34 bin
1054396 -rw-rw-r-- 1 tod tod 7696 ott 18 15 :21 commands.c
1045205 -rw-rw-r-- 1 tod tod 1233 ott 16 23:14 commands.h
1045208 -rw-rw-r-- 1 tod tod 952 ott 18 17 :10 list.c
1057517 -rw-rw-r-- 1 tod tod 244 ott 18 15:22 list.h
1055205 -rw-r - r-- 1 tod tod 487 ott 18 02:36 main.c
1150595 drwxr-xr-x 3 tod tod 4096 ott 18 02:34 obj
1057590 -rw-rw-r-- 1 tod tod 1213 ott 18 09:33解析。 c
1057622 -rw-rw-r-- 1 tod tod 193 ott 18 09:33 parsing.h
1055154 -rw-rw-r-- 1 tod tod 1368 ott 18 02:51 shelldeb。 cbp
1057688 -rw-rw-r-- 1 tod tod 665 ott 18 15:22 shelldeb.depend
1057721 -rw-rw-r-- 1 tod tod 1413 ott 18 23:20 shelldeb。布局

/ home / tod / prog ramming / shelldeb / bin:
totale 4
1150598 drwxr-xr-x 3 tod tod 4096 ott 20 14:02调试

/ home / tod / programming / shelldeb / bin / Debug:
totale 4
1150684 drwxrwxr-x 4 tod tod 4096 ott 20 14:02 r55

/ home / tod / programming / shelldeb / bin / Debug / r55:
totale 8
1150685 drwxrwxr-x 2 tod tod 4096 ott 20 14:03 tmpfolder
1150686 drwxrwxr-x 2 tod tod 4096 ott 20 14:02 tmpfolder2

/ home / tod / programming / shelldeb / bin / Debug / r55 / tmpfolder:
totale 0
1045360 -rw-rw-r-- 1 tod tod 0 ott 20 14:03 myfile

/ home / tod / programming / shelldeb / bin / Debug / r55 / tmpfolder2:
totale 0

/ home / tod / programming / shelldeb / obj:
totale 4
1150596 drwxr-xr-x 3 tod tod 4096 ott 20 14:01调试

/ home / tod / programming / shelldeb / obj / Debug:
totale 20
1046334 -rw-rw-r-- 1 tod tod 15088 ott 18 17:10 commands.o
1046232 -rw-rw-r-- 1 tod tod 0 ott 20 14:01 comment.txt
1150683 drwxrwxr-x 2 tod tod 4096 ott 20 14:02 tmpfolder

/ home / tod / programming / shelldeb / obj / Debug / tmpfolder:

当前输出运行我的shell:

 > list / home / tod / programming / shelldeb -r 
上市:/ home / tod / programming / shelldeb
1057517 -rw-rw-r-- 1 1000 1000 244 list.h
1054396 -rw-rw-r-- 1 1000 1000 7696 commands.c
1057590 -rw-rw-r-- 1 1000 1000 1213 parsing.c
1150597 drwxr-xr-x 3 1000 1000 4096 bin
1045208 -rw-rw-r-- 1 1000 1000 952 list.c
1055154 -rw-rw-r-- 1 1000 1000 1368 shelldeb.cbp
1150595 drwxr-xr-x 3 1000 1000 4096 obj
1045205 -rw-rw-r-- 1 1000 1000 1233 commands.h
1057688 -rw-rw-r-- 1 1000 1000 665 shelldeb.depend
1057721 -rw-rw-r-- 1 1000 1000 1413 shelldeb.layout
1057622 -rw-rw-r-- 1 1000 1000 193 parsing.h
1055205 -rw-r - r-- 1 1000 1000 487 main.c
上市:obj
1150596 drwxr-xr-x 3 1000 1000 4096调试
上市:Debug
1046232 -rw-rw-r-- 1 1000 1000 0 comment.txt
1150683 drwxrwxr-x 2 1000 1000 4096 tmpfolder
1046334 -rw-rw-r-- 1 10 00 1000 15088 commands.o
上市:tmpfolder
1054413 -rw-rw-r-- 1 1000 1000 0 tmp.txt


解决方案

我终于设法以非常简单的方式编写了递归列表功能。我在c标准库中找到了函数nftw(),基本上它完成了所有的工作。
这里是谁可以感兴趣的代码:

  static int list(const char * path)
{
char call_dir [MAXDIRLEN];
DIR * dirstream;
struct dirent * dir_entry;
struct stat file_data;

getcwd(call_dir,MAXDIRLEN);
dirstream = opendir(path);

if(dirstream == NULL)
{
perror(Error:can not open directory\\\
);
return -1;
}
chdir(path);

while((dir_entry = readdir(dirstream))!= NULL)
{
if(!ISSET_A_FLAG(options))
{
if dir_entry-> d_name [0] =='。')
continue;
}
if(!ISSET_S_FLAG(options))
{
stat(dir_entry-> d_name,& file_data);
printStat(& file_data);
}
printf(%s,dir_entry-> d_name);
printf(\\\
);
}
closedir(dirstream);
chdir(call_dir);
return 0;
}

static int list_R(const char * entry_path,const struct stat * entry_stat,int typeflag,struct FTW * ftwbuf)
{
int status;
if(typeflag& FTW_D)
{
printf(\\\
Content of%s:\\\
,entry_path);
status = list(entry_path);
}
if(status == -1)
return status;
return 0;
}

这两个函数只需要实现打印信息的printstat()目录条目。
一个简单的调用nftw(path,list_R,1,ftw_flags);设置FTW_PHYS标志后,该作业。


I'm failing at writing this function correctly. It should be listing recursively the content the path provided by the first argument (like ls -R), but it stops too soon. Here is the code, the expected output and the output I get:

int browseDir (const char *path, const int *options)
{
    char callingdir[MAXDIRLEN];
    char currentdir[MAXDIRLEN];

    getcwd(callingdir,MAXDIRLEN);

    DIR *dirstream;
    struct dirent *dir_entry; 
    struct stat file_data;
    LIST subd_list = newList();

    if (path == NULL)
        strcpy(currentdir,callingdir);
    else
        strcpy(currentdir,path);

    dirstream = opendir(currentdir);
    printf("Listing: %s\n",currentdir);
    chdir(currentdir);

    if (dirstream == NULL)
    {
        perror("Error: cannot open directory\n");
        return 0;
    }

    while((dir_entry = readdir(dirstream)) != NULL)
    {
        if (!ISSET_A_FLAG(*options))
        {
            if (dir_entry->d_name[0]=='.')
                continue;
        }
        if (!ISSET_S_FLAG(*options))
        {
            stat(dir_entry->d_name, &file_data);
            printStat(&file_data);
        }
        printf("%s ",dir_entry->d_name);
        printf("\n");
        if (ISSET_R_FLAG(*options) && (dir_entry->d_type & DT_DIR) && strcmp(dir_entry->d_name,".") && strcmp(dir_entry->d_name,".."))
            addNode(subd_list, dir_entry->d_name);
    }
    closedir(dirstream);

    while(!isEmpty(subd_list))
    {
        browseDir((*subd_list)->data, options);
        delNode(subd_list);
    }

    chdir(callingdir);
    return 0;  
}

output using ls -Rli (expected)

tod@iTod:~/Dropbox/programming/SO/myshell2$ ls -lRi /home/tod/programming/shelldeb
/home/tod/programming/shelldeb:
totale 52
1150597 drwxr-xr-x 3 tod tod 4096 ott 18 02:34 bin
1054396 -rw-rw-r-- 1 tod tod 7696 ott 18 15:21 commands.c
1045205 -rw-rw-r-- 1 tod tod 1233 ott 16 23:14 commands.h
1045208 -rw-rw-r-- 1 tod tod  952 ott 18 17:10 list.c
1057517 -rw-rw-r-- 1 tod tod  244 ott 18 15:22 list.h
1055205 -rw-r--r-- 1 tod tod  487 ott 18 02:36 main.c
1150595 drwxr-xr-x 3 tod tod 4096 ott 18 02:34 obj
1057590 -rw-rw-r-- 1 tod tod 1213 ott 18 09:33 parsing.c
1057622 -rw-rw-r-- 1 tod tod  193 ott 18 09:33 parsing.h
1055154 -rw-rw-r-- 1 tod tod 1368 ott 18 02:51 shelldeb.cbp
1057688 -rw-rw-r-- 1 tod tod  665 ott 18 15:22 shelldeb.depend
1057721 -rw-rw-r-- 1 tod tod 1413 ott 18 23:20 shelldeb.layout

/home/tod/programming/shelldeb/bin:
totale 4
1150598 drwxr-xr-x 3 tod tod 4096 ott 20 14:02 Debug

/home/tod/programming/shelldeb/bin/Debug:
totale 4
1150684 drwxrwxr-x 4 tod tod 4096 ott 20 14:02 r55

/home/tod/programming/shelldeb/bin/Debug/r55:
totale 8
1150685 drwxrwxr-x 2 tod tod 4096 ott 20 14:03 tmpfolder
1150686 drwxrwxr-x 2 tod tod 4096 ott 20 14:02 tmpfolder2

/home/tod/programming/shelldeb/bin/Debug/r55/tmpfolder:
totale 0
1045360 -rw-rw-r-- 1 tod tod 0 ott 20 14:03 myfile

/home/tod/programming/shelldeb/bin/Debug/r55/tmpfolder2:
totale 0

/home/tod/programming/shelldeb/obj:
totale 4
1150596 drwxr-xr-x 3 tod tod 4096 ott 20 14:01 Debug

/home/tod/programming/shelldeb/obj/Debug:
totale 20
1046334 -rw-rw-r-- 1 tod tod 15088 ott 18 17:10 commands.o
1046232 -rw-rw-r-- 1 tod tod     0 ott 20 14:01 comment.txt
1150683 drwxrwxr-x 2 tod tod  4096 ott 20 14:02 tmpfolder

/home/tod/programming/shelldeb/obj/Debug/tmpfolder:

current output running my shell:

> list /home/tod/programming/shelldeb -r
Listing: /home/tod/programming/shelldeb
1057517 -rw-rw-r--  1 1000 1000      244 list.h 
1054396 -rw-rw-r--  1 1000 1000     7696 commands.c 
1057590 -rw-rw-r--  1 1000 1000     1213 parsing.c 
1150597 drwxr-xr-x  3 1000 1000     4096 bin 
1045208 -rw-rw-r--  1 1000 1000      952 list.c 
1055154 -rw-rw-r--  1 1000 1000     1368 shelldeb.cbp 
1150595 drwxr-xr-x  3 1000 1000     4096 obj 
1045205 -rw-rw-r--  1 1000 1000     1233 commands.h 
1057688 -rw-rw-r--  1 1000 1000      665 shelldeb.depend 
1057721 -rw-rw-r--  1 1000 1000     1413 shelldeb.layout 
1057622 -rw-rw-r--  1 1000 1000      193 parsing.h 
1055205 -rw-r--r--  1 1000 1000      487 main.c 
Listing: obj
1150596 drwxr-xr-x  3 1000 1000     4096 Debug 
Listing: Debug
1046232 -rw-rw-r--  1 1000 1000        0 comment.txt 
1150683 drwxrwxr-x  2 1000 1000     4096 tmpfolder 
1046334 -rw-rw-r--  1 1000 1000    15088 commands.o 
Listing: tmpfolder
1054413 -rw-rw-r--  1 1000 1000        0 tmp.txt 

解决方案

I finally managed to write a recursive-listing function in a very simple way. I found the function nftw() in the c standard library, and basically it does all the work. Here is the code for who can be interested:

static int list (const char *path) 
{
  char calling_dir[MAXDIRLEN];
  DIR *dirstream;
  struct dirent *dir_entry; 
  struct stat file_data;

  getcwd(calling_dir,MAXDIRLEN);  
  dirstream=opendir(path);

  if (dirstream == NULL)
    {
      perror("Error: cannot open directory\n");
      return -1;
    }
  chdir(path);

  while((dir_entry = readdir(dirstream)) != NULL)
    {
      if (!ISSET_A_FLAG(options))
    {
      if (dir_entry->d_name[0]=='.')
        continue;
    }
      if (!ISSET_S_FLAG(options))
    {
      stat(dir_entry->d_name, &file_data);
      printStat(&file_data);
    }
      printf("%s ",dir_entry->d_name);
      printf("\n");
    }
  closedir(dirstream);
  chdir(calling_dir);
  return 0; 
}

static int list_R (const char *entry_path, const struct stat *entry_stat,int typeflag,struct FTW *ftwbuf)
{
  int status;
  if(typeflag & FTW_D)
    {
      printf("\nContent of %s : \n",entry_path);
      status=list(entry_path);
    }
  if (status == -1)
    return status;
  return 0;
}

with those two functions you just have to implement printstat() that prints infos on the directory entry. A simple call to nftw(path,list_R,1,ftw_flags); after setting FTW_PHYS flag does the job.

这篇关于递归列出目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆