C语言如何实现遍历目录的功能

如何用C语言实现linux下的ls命令

转载自:CND8学院(http://school.cnd8.com/c/jiaocheng/60408.htm)


 

  首先我讲一下写这篇东西的目的。我觉得对于很多linux新手。尤其是在自学的同学。最好的学习的方法就是通过具体的例子。通过一个实践的例子,在学习相关的知识点的同时,就把它们应用到这例子中。这样不仅知道了原理。也知道了怎么去应用。下面就开始用一个常用的命令”ls”开始。所有的东西都是从最基本的原理开始。一步步来教你怎么实践出一个命令
    (一)ls命令简单介绍
    第一步当然是要明白ls究竟是做什么的。如果你要做一个东西却不知道要用来干嘛。会不会很搞笑?所以下面就简单的介绍ls命令的作用和怎么使用

    1.Ls可以列出文件名和文件的属性
    在命令行输入ls:

    ls 命令.jpg

    Ls的默认动作是找出当前所有文件的文件名。按字典排序后输出。
    Ls还能显示其他的信息。如果加上-l就会列出每个文件的详细信息。也叫ls的长格式:

    ls -l命令.jpg


    2.        列出指定目录或文件的信息
    Linux系统中会有很多目录。每个目录中又会有很多文件。如果要列出一个非当前目录的内容或者是一个特定文件的信息,则需要在参数中给出目录名或文件名。如:
    ls /tmp //列出/tmp目录中各文件的文件名
    ls – docs //列出docs目录中各文件的属性
    ls *.c //列出当前目录下与*.c匹配的文件,即当前目录下所有以.c为后缀的文件

    3.        经常用到的命令行选项
    ls -l 在前面已经提到过,-l就是输出文件详细的信息。也叫长格式;
    ls -a 列出的内容包含以“.“开头的让文件,即所谓有隐藏文件
    ls –lu 显示最后访问时间
    ls –t 输出时按时间排序
    ls –F 显示文件类型

    ls 命令的参数选项非常多,大多也可以组合使用。所以还是比较复杂的。但是我们第一步要实现的就是它最基本的功能:列出当前目录下的所有文件或子目录。

    (二)学习必备的知识

    既然是列出文件和目录,那么肯定是和linux文件系统有关系的,所以要写ls命令,至少要对文件系统的基本原理有一定的了解。为了不至于使这个帖子内容过于复杂,我把这方面的知识介绍单独开了一个帖子:
    linux 文件系统详解

    如果你对这些已经有所了解。就会知道linux下的文件都是以/为根目录的树型结构,虽然linux下有普通文件、目录文件、链接文件、设备文件、管道文件这几种类型。但链接文件、设备文件、管道文件都可以当做普通文件看待,那实际也就只要区分普通文件和目录文件这两种了。而目录文件的内容就是它所包含所有文件和子目录的一个列表,所以只要打开目录文件并读取对应目录块里的那个列表数据,就可以得到些目录下所有文件和子目录的名称了。其实这个流程简单,就是:打开目录->读取内容->显示文件名称->关闭打开的目录。用伪代码流程表示如下:
    Mani(){
    Opendir
    While(readdir)
    Print d_name
    Closedir;
    }
     那么现在的问题是用什么函数去打开并读目录呢?又是怎么样来读出数据呢?这里介绍是的opendir 和readdir,但是可能对于一些新手来说,就算知道了函数名称也不一定知道怎么用。别急,下一步就是教你怎么去查相应函数的帮助资料。
    linux下查看帮助手册的命令是man,关于man的详细介绍在这个帖子里我有详细介绍:linux 帮助手册页命令 man详解 如果对这方面还不是很清楚的可以先去学习一下。
    好了,如果你已经明白man的用法,我们就开始查看opendir和readdir的用法
    我们在命令行输入:
    # man 3 opendir

怎样使用C语言列出某个目录下的文件?

转载自:http://see.xidian.edu.cn/cpp/html/1548.html

C语言本身没有提供象dir_list()这样的函数来列出某个目录下所有的文件。不过,利用C语言的几个目录函数,你可以自己编写一个dir_list()函数。   

首先,头文件dosh定义了一个find_t结构,它可以描述DOS下的文件信息,包括文件名、时间、日期、大小和属性。其次,C编译程序库中有_dos_findfirst()_dos_findnext()这样两个函数,利用它们可以找到某个目录下符合查找要求的第一个或下一个文件。   

dos_findfirst()函数有三个参数,第一个参数指明要查找的文件名,例如你可以用“*.*”指明要查找某个目录下的所有文件。第二个参数指明要查找的文件属性,例如你可以指明只查找隐含文件或子目录。第三个参数是指向一个find_t变量的指针,查找到的文件的有关信息将存放到该变量中。   

dos_findnext()函数在相应的目录中继续查找由_dos_findfirst()函数的第一个参数指明的文件。_dos_findnext()函数只有一个参数,它同样是指向一个find_t变量的指针,查找到刚文件的有关信息同样将存放到该变量中。

利用上述两个函数和find_t结构,你就可以遍历磁盘上的某个目录,并列出该目录下所有的文件,请看下例:   

#include <stdio.h>

#include <direct.h>

#include <dos.h>

#include <malloc.h>

#include <memory.h>

#include <string.h>

typedef struct find_t FILE_BLOCK

void main(void);

void main(void)

{

      FILE_BLOCK f-block;         /* Define the find_t structure variable * /

      int   ret_code;             / * Define a variable to store the return codes * /

      / * Use the "*.*" file mask and the 0xFF attribute mask to list

           all files in the directory, including system files, hidden

           files, and subdirectory names.  * /

      ret_code = _dos_findfirst(" *. * ", 0xFF, &f_block);

      /* The _dos_findfirst() function returns a 0 when it is successful

         and has found a valid filename in the directory.  * /

     while (ret_code == 0)

     {

          /* Print the file's name * /

          printf(" %-12s\n, f_block, name);

          / * Use the -dos_findnext() function to look

               for the next file in the directory.  * /

          ret_code = _dos_findnext (&f_block);

     }

     printf("\nEnd of directory listing. \n" );

}

//-------------------------------------------------

linux下用C语言历遍目录( C语言列出目录)

转载自:http://blog.sina.com.cn/s/blog_49ea99e10100f40z.html

linux下历遍目录的方法一般是这样的:

打开目录-》读取-》关闭目录

相关函数是(函数原形)

opendir -> readdir -> closedir

#include <dirent.h>

DIR *opendir(const char *dirname);

#include <dirent.h>

struct dirent *readdir(DIR *dirp);

#include <dirent.h>

int closedir(DIR *dirp);

dirent.h这个头文件,包括了目录的一些函数。

opendir用于打开目录,是类似于流的那种方式,返回一个指向DIR结构体的指针,他的参数*dirname是一个字符数组或者字符串常量。

readdir函数用于读取目录,他只有一个参数,这个参数主要是opendir返回的结构体指针。

dirent的结构如下定义

                   struct dirent

                   {

                       long d_ino;                     

                       off_t d_off;                    

                       unsigned short d_reclen;        

                       char d_name [NAME_MAX+1];       

                   }

结构体中d_ino存放的是该文件的结点数目;

d_off 是文件在目录中的编移;

short d_reclen是这个文件的长度;

程序如下:

#include apue.h"

#include <dirent.h>

int

main(int argc ,char *argv[])

{

       DIR         *dp;

       struct dirent   *dirp;

     

       if(argc!=2)

             err_quit("usage: ls directory_name");

       if((dp=opendir(argv[1]))==NULL)

              err_sys("can't open %s",argv[1]);

      while((dirp=readdir(dp))!=NULL)

              printf("%s\n",dirp->d_name);

     closedir(dp);

     exit(0);

}

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

#include <dirent.h>

void print_usage(void);

void print_usage(void)

{

printf("Usage: test dirname\n");

}

int main(int argc,char *argv[])

{

DIR * dp;

struct dirent *filename;

if (argc < 2)

{

       print_usage();

       exit(1);

}

dp = opendir(argv[1]);

if (!dp)

{

       fprintf(stderr,"open directory error\n");

       return 0;

}

while (filename=readdir(dp))

{

       printf("filename:%-10s\td_info:%ld\t d_reclen:%us\n",

         filename->d_name,filename->d_ino,filename->d_reclen);

}

closedir(dp);

return 0;

}

sudo gcc readdir.c

 ./a.out /home/growliming

结果如下:

filename:APUE.chm      d_info:16746     d_reclen:20s

filename:src.tar.gz    d_info:1063454     d_reclen:24s

filename:c             d_info:24536     d_reclen:16s

filename:apue.2e       d_info:32874     d_reclen:20s

filename:..            d_info:16353     d_reclen:16s

filename:.             d_info:16708     d_reclen:16s

//-----------------------------------------------------------------

c语言列出文件夹中的文件

转载自:http://blog.csdn.net/gotoxy/article/details/1872332

/*  TC2.0 下编译*/

#include "stdio.h"

#include "stdlib.h"

#include "dir.h"

#include "dos.h"

#define wait() getch()

/*

============目录函数(原型声明所在头文件为dir.hdos.h================

int     chdir(char *path) 使指定的目录path(如:"C://WPS")变成当前的工作目录,

         功返回0

int findfirst(char *pathname,struct ffblk *ffblk,int attrib)查找指定的文件,成功

     返回0

     pathname为指定的目录名和文件名,"C://WPS//TXT"

     ffblk为指定的保存文件信息的一个结构,定义如下:

    ┏━━━━━━━━━━━━━━━━━━┓

    ┃struct ffblk                        

    ┃{                                   

    ┃ char ff_reserved[21]; //DOS保留字  ┃

    ┃ char ff_attrib;       //文件属性   ┃

    ┃ int  ff_ftime;        //文件时间   ┃

    ┃ int  ff_fdate;        //文件日期   ┃

    ┃ long ff_fsize;        //文件长度   ┃

    ┃ char ff_name[13];     //文件名     ┃

    ┃}                                   

    ┗━━━━━━━━━━━━━━━━━━┛

     attrib为文件属性,由以下字符代表

    ┏━━━━━━━━━┳━━━━━━━━┓

    ┃FA_RDONLY 只读文件┃FA_LABEL  卷标号┃

    ┃FA_HIDDEN 隐藏文件┃FA_DIREC  目录  ┃

    ┃FA_SYSTEM 系统文件┃FA_ARCH   档案  ┃

    ┗━━━━━━━━━┻━━━━━━━━┛

    例:

    struct ffblk ff;

    findfirst("*.wps",&ff,FA_RDONLY);

int   findnext(struct ffblk *ffblk)      取匹配finddirst的文件,成功返回0

*/

void formatExt(char *dstr,char *sstr)

{

    sscanf(sstr,"[^///:*?/"<>|]",dstr);

}

typedef int (*METHOD)();

int enum_allFile(METHOD method,char *dir,char *type,int filter)

{/*

method==NULL 仅显示文件名

dir==NULL 当前文件夹

*/

    static struct ffblk ff;

    static int ct,run_method;

 run_method=0;

    if(type!=NULL){

        if(dir!=NULL) {

            if(chdir(dir)){

                puts("folder can't found!");

                wait();

                exit(1);

            }

        }

        formatExt(type,type);

        if(findfirst(type,&ff,filter)) {

            puts("can't find file!");

            ct=0;

            return 0;

        }

        ct=1;

  run_method=1;

    }

    else {

            if(findnext(&ff) ==0){

                ct++;

    run_method=1;

            }

            else return ct;

    }

 if(run_method){

  if(method!=NULL) method(ff.ff_name);

  else printf("/n%s",ff.ff_name);

 }

    enum_allFile( method,NULL, NULL, 0);

    return ct;

}

void TestFunc(char *fname)

{

puts(fname);

}

int main()

{

 int ct;

 ct=enum_allFile( TestFunc, NULL, "*.c", FA_RDONLY | FA_HIDDEN | FA_SYSTEM );/* */

 printf("/n--------------%d-------------/n",ct);

 wait();

 return 0;

}

Linux中用C语言实现目录检索和返回所有文件

转载自:http://blog.sina.com.cn/s/blog_48a83572010002p6.html

    大家都知道,使用递归调用的方法可以完成对指定目录及其所有子目录的遍历.这在WINDOW下是不难实现的.而在LINUX,由于我没有找到相关的实例.所以自己动手做了一个.请大家指正.

/*

 * FUNCTION     : ReadPath

 * ABSTRACT     : Get the file name from path and is't child path

 * PARAMETER    :

 *       char* path      

 *       char file[FILE_CNT_MAX][256]       the all files path and name int the specified path

 * RETURN       :

 *       0       OK

 *      -1       FALSE

 * CREATE       : 2006-01-05    ZHANG.JINCUN

 * NOTE         :

 */

int g_iFileCnt = 0;

int ReadPath(char* path, char file[][256], char* filefmt)

{

    DIR * pdir;

    struct dirent * ptr;

    char newpath[256];

    struct stat filestat;

    if(stat(path, &filestat) != 0){

        printf("The file or path(%s) can not be get stat!\n", newpath);

        return -1;

    }

    if((filestat.st_mode & S_IFDIR) != S_IFDIR){

        printf("(%s) is not be a path!\n", path);

        return -1;

    }

    pdir =opendir(path);

    while((ptr = readdir(pdir))!=NULL)

    {

        if(g_iFileCnt + 1 > FILE_CNT_MAX){

            printf("The count of the files is too much(%d > %d)!\n", g_iFileCnt + 1, FILE_CNT_MAX);

            break;

        }

        if(strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)  continue;

        sprintf(newpath,"%s/%s", path,ptr->d_name);

        if(stat(newpath, &filestat) != 0){

            printf("The file or path(%s) can not be get stat!\n", newpath);

            continue;

        }

        /* Check if it is path. */

        if((filestat.st_mode & S_IFDIR) == S_IFDIR){

            if(ReadPath(newpath, file, filefmt) != 0){

                printf("Path(%s) reading is fail!\n", newpath);

                continue;

            }

        }else if((filestat.st_mode & S_IFREG) == S_IFREG){

            if(filefmt[0] != '\0'){

                char* p;

                if((p = strrchr(ptr->d_name,'.')) == 0) continue;

                

                char fileformat[64];

                char* token;

                strcpy(fileformat, filefmt);        

                if((token = strtok( fileformat,";")) == NULL){

                    strcpy(file[g_iFileCnt], newpath);

                    g_iFileCnt++;

                    continue;

                }else{

                    if(strcasecmp(token,p) == 0){

                        strcpy(file[g_iFileCnt], newpath);

                        g_iFileCnt++;

                        continue;

                    }

                }

                while((token = strtok( NULL,";")) != NULL){

                    if(strcasecmp(token,p) == 0){

                        strcpy(file[g_iFileCnt], newpath);

                        g_iFileCnt++;

                        continue;

                    }                }

            }else{

                strcpy(file[g_iFileCnt], newpath);

                g_iFileCnt++;

            }

        }

    }

    closedir(pdir);

    return 0;   

}

    在上面的ReadPath()函数中,参数char* path是你要检索的目录,其内部可以有子目录;char file[][256]是检索结果,存放所有匹配的文件名;char* filefmt是你需要返回文件的类型,例如".cc;.c;.h".

    请大家帮我看看这个函数的性能,也供大家参考使用.本函数已经在LINUX上运行通过.

    本函数本人所有.请勿商业使用.谢谢!

原文地址:https://www.cnblogs.com/techstone/p/2761880.html