文件夹操作: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 */
};