首页 > 代码库 > Linux系统编程之访问文件夹及其文件属性

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

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

2. 文件属性:lstat

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

#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 */
           };