概览

  1. 文件夹操作:opendir, readdir, closedir

  2. 文件属性:lstat

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

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#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也行)

1
2
3
4
5
6
7
8
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 */
           };
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
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 */
           };