Linux下文件及目录的一些操作(附递归遍历目录源码)

1.获取当前工作目录

#include <unistd.h>
char *getcwd(char *buf, size_t size);

参数:
    buf:缓冲区地址。
    size:给出的最大路径名长度。
返回值:
    如果当前工作目录的路径名长度大于给定的长度,则返回NULL并置errno为ERANGE。
    函数调用成功时,返回指向路径名的指针;否则返回NULL
示例:
    char pathname[256] = {0};
    if(getcwd(pathname, sizeof(pathname))!=NULL) {
        printf("current dir is: %s\n", pathanme);
    }

2. stat结构体


    #include <sys/stat.h>

    struct stat {
      mode_t st_mode;       //文件类型和权限信息
      ino_t st_ino;         //i结点标识
      dev_t st_dev;         //device number (file system)
      dev_t st_rdev;        //device number for special files
      nlink_t st_nlink;     //符号链接数
      uid_t st_uid;         //用户ID
      gid_t st_gid;         //组ID
      off_t st_size;        //size in bytes,for regular files
      time_t st_st_atime;   //最后一次访问的时间
      time_t st_mtime;      //文件内容最后一次被更改的时间
      time_t st_ctime;      //文件结构最后一次被更改的时间
      blksize_t st_blksize; //best I/O block size
      blkcnt_t st_blocks;   //number of disk blocks allocated
    }
获取文件stat结构体信息的三个函数

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *path, struct stat *buf);
int fstat(int fieldes, struct stat *buf);
int lstat(const char *path, struct stat *buf);

返回值:
    成功则返回0,否则返回-1.
说明:
    1. fstat的第一个参数int fields为文件描述符。
    2. fstat区别于另外两个系统调用的地方在于,fstat系统调用接受的是 一个“文件描述符”,而另外两个则直接接受“文件全路径”。文件描述符是需要我们用open系统调用后才能得到的,而文件全路径直接写就可以了。
    3. stat与lstat的区别:当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;而stat返回的是该链接指向的文件的信息。可以这样记,lstat比stat多了一个l,因此它是有本事处理符号链接文件(link)本身的。

3.dirent结构体,可以只关注d_name字段


    #include <dirent.h>
    struct dirent
    {
      long d_ino;                /* inode number 索引节点号 */   
      off_t d_off;               /* offset to this dirent 在目录文件中的偏移 */  
      unsigned short d_reclen;   /* length of this d_name 文件名长 */  
      unsigned char d_type;      /* the type of d_name 文件类型 */
      char d_name [NAME_MAX 1];  /* file name (null-terminated) 文件名,最长255字符 */  
    }

4.读取目录的操作
 


    //可能用到的函数
    #include <sys/types.h>
    #include <dirent.h>

    DIR *opendir(const char *dirname);
    struct dirent *readir(DIR *dirp);
    void rewinddir(DIR *dirp);
    int closedir(DIR *dirp);
    //一个完整的递归遍历目录下子目录及文件的函数
    #include <unistd.h>
    #include <stdio.h>
    #include <dirent.h>
    #include <string.h>
    #include <stdlib.h>

    void printdir(char *dir, int depth) 
    {
        DIR *dp;
        struct direct *entry;
        struct stat statbuf;

        if((dp = opendir(dir)) != NULL) {
            //changedir,进入dir目录
            chdir(dir);

            while( (entry = readdir(dp)) != NULL ) {
                lstat(entry->d_name, &statbuf);

                if( S_ISDIR(statbuf.st_mode) ) {
                    if(strcmp(".",entry->d_name)==0 || strcmp("..",entry->d_name) {
                        continue;
                }

                    printf("%*s%s/\n",depth," ",entry->d_name);
                    printdir(entry->d_name,depth+4);
                } else {
                    printf("%*s%s\n",depth," ",entry->d_name);
                }
            }

            chdir("..");
            closedir(dp);

        } else {
            fprintf(stderr,"cannot open directory: %s\n",dir);
            return;
        }
    }

    int main(int argc, char *argv[])
    {
        printf("Directory scan of /home:\n");
        printdir("/home",0);
        printf("Success!\n");

        exit(0);
    }

 5.注意:判断文件是目录文件还是普通文件有两种方式   

    struct dirent *entry;
    struct stat st;

    entry = opendir(dir);
    lstat(entry->d_name,&st);
    S_ISDIR(st.st_mode); //是目录文件则函数返回true
    S_ISREG(st.st_mode); //是普通文件则函数返回true

    //S_ISDIR和S_ISREG均为宏定义,可参见sys/stat.h.
    //或者用以下方式
    (st.st_mode & S_IFMT)==S_IFDIR //目录文件为true
    (st.st_mode & S_IFMT)==S_IFREG //普通文件为true
    //其中S_IFMT在sys/stat.h中被定义为八进制数170000,通过与st_mode进行位的与操作可得类型,另有S_IFBLK、S_IFCHR、S_IFIFO类型
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值