Linux系统编程|访问文件夹及其文件属性

进击的代码 2024-10-16 21:39:53

概览

文件夹操作:opendir, readdir, closedir

文件属性:lstat

实现功能:获取指定文件夹下所有的文件(使用递归),因此就能计算所有文件大小之类的啦。。。

代码示例如下:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <errno.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <dirent.h>

#define BUF_SIZE 512

static char _get_file_type(mode_t st_mode);

static int _folder_file_read(const char * path);

// read all file of the path

int folder_file_read(const char * path);

//*********** man func for test ************//

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

{

int ret;

if (argc != 2)

{

printf("usage: ./a.out path \n");

return 1;

}

ret = folder_file_read(argv[1]);

if (-1 == ret)

{

printf("%s is not a valid dir path!\n", argv[1]);

return 1;

}

return 0;

}

int folder_file_read(const char * path)

{

int ret;

ret = _folder_file_read(path);

if (-1 == ret)

{

return -1;

}

printf("\n");

return 0;

}

static int _folder_file_read(const char * path)

{

DIR *dir;

struct dirent *entry;

struct stat st_stat;

int ret;

char full_path[BUF_SIZE];

char type;

dir = opendir(path);

if (NULL == dir)

{

perror("opendir()");

ret = -1;

goto err_opendir;

}

while (1)

{

entry = readdir(dir);

if (NULL == entry) //end

{

break;

}

snprintf(full_path, BUF_SIZE, "%s/%s", path, entry->d_name);

ret = lstat(full_path, &st_stat);

if (-1 == ret)

{

perror("lstat()");

goto err_lstat;

}

type = _get_file_type(st_stat.st_mode);

// handle diff type

if ('d' == type) // dir

{

if (0 == strcmp(".", entry->d_name) || 0 == strcmp("..", entry->d_name))

{

continue;

}

_folder_file_read(full_path); // must be success

}

else // else, others

{

// do something here

printf("%s\t", entry->d_name);

}

}

closedir(dir);

return 0;

err_lstat:

closedir(dir);

err_opendir:

return ret;

}

static char _get_file_type(mode_t st_mode)

{

if (S_ISREG(st_mode))

{

return '-';

}

if (S_ISDIR(st_mode))

{

return 'd';

}

if (S_ISCHR(st_mode))

{

return 'c';

}

if (S_ISBLK(st_mode))

{

return 'b';

}

if (S_ISFIFO(st_mode))

{

return 'p';

}

if (S_ISLNK(st_mode))

{

return 'l';

}

if (S_ISSOCK(st_mode))

{

return 's';

}

return 0; // no meaning

}

运行结果最后

附两个结构体的成员,struct dirent, struct stat st_stat(自己man也行)

struct dirent {

ino_t          d_ino;       /* inode number */

off_t          d_off;       /* not an offset; see NOTES */

unsigned short d_reclen;    /* length of this record */

unsigned char  d_type;      /* type of file; not supported

by all filesystem types */

char           d_name[256]; /* filename */

};

---

struct stat {

dev_t     st_dev;     /* ID of device containing file */

ino_t     st_ino;     /* inode number */

mode_t    st_mode;    /* protection */

nlink_t   st_nlink;   /* number of hard links */

uid_t     st_uid;     /* user ID of owner */

gid_t     st_gid;     /* group ID of owner */

dev_t     st_rdev;    /* device ID (if special file) */

off_t     st_size;    /* total size, in bytes */

blksize_t st_blksize; /* blocksize for filesystem I/O */

blkcnt_t  st_blocks;  /* number of 512B blocks allocated */

time_t    st_atime;   /* time of last access */

time_t    st_mtime;   /* time of last modification */

time_t    st_ctime;   /* time of last status change */

};

0 阅读:4

进击的代码

简介:程序员,分享生活、工作、技术、学习。