1.打开目录 -- opendir
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
参数:
name:要打开的目录名
返回值:
成功返回目录流指针,返回NULL;
2.读取目录 -- readdir
注:readdir 一次只能随机读取一个目录项
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
struct dirent {
char d_name[256]; /*文件名*/
};
注意它的返回值类型是结构体,所以在调用时就要定义同类型(struct dirent)的变量来接收它
3.关闭目录 -- closedir
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
参数:
dirp:目录流指针
返回值:
成功返回0,失败返回-1
4.获取文件属性 -- lstat
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *statbuf);
int fstat(int fd, struct stat *statbuf);
int lstat(const char *pathname, struct stat *statbuf);
参数:
pathname:文件名
statbuf:存放文件信息的结构体地址
返回值:
成功返回0,失败返回-1;
struct stat
{
mode_t st_mode; //文件类型和权限
nlink_t st_nlink; //文件硬链接数
uid_t st_uid; //用户ID
gid_t st_gid; //用户组ID
off_t st_size; //文件大小
struct timespec st_mtim; //最后修改文件时间
#define st_mtime st_mtim.tv_sec
}
#include <sys/types.h>
#include <grp.h>
struct group *getgrnam(const char *name);
struct group *getgrgid(gid_t gid);
getgrgid -- 得到用户组名的函数
getpwuid -- 得到用户名的函数
这里注意lstat的形参也是结构体形,这里把这个结构体的成员也罗列出来了,还罗列了getgrgid 和 getpwuid 函数;
5.获取文件类型
S_IFMT 0170000 bit mask for the file type bit field
S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO
如果 st_mode & S_IFMT等于对应文件类型宏,则文件类型宏对应类型就为文件类型
获取文件权限:
st_mode & 对应权限宏 == 宏本身 表示具有该权限
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
6.例子--用目录IO操作实现 ls -l 的功能
/*===============================================
* 文件名称:myls.c
* 创 建 者:zhouhao
* 创建日期:2022年08月06日
* 描 述:
================================================*/
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <grp.h>
#include <pwd.h>
int main(int argc, char *argv[])
{
int ret = 0;
struct stat info; //创建存放文件信息的结构体
struct tm *t = NULL; //存放时间信息的结构体
struct group *gp = NULL; //存放用户组信息的结构体
struct passwd *usr = NULL; //存放用户信息的结构体
DIR *dir = opendir("."); //打开目录得到目录流指针
if(NULL == dir)
{
perror("opendir");
return -1;
}
struct dirent *buf = NULL;
while( (buf = readdir(dir)) != NULL) //循环遍历目录得到每一个目录项
{
if(buf->d_name[0] != '.') //不显示隐藏文件
{
ret = lstat(buf->d_name, &info); //通过文件名得到文件信息
if(ret < 0)
{
perror("lstat");
return -1;
}
char stmode[20];
memset(stmode, '-', sizeof(stmode));
if(S_ISREG(info.st_mode)) /* regular file */
{
stmode[0] = '-';
}
if(S_ISDIR(info.st_mode))
{
stmode[0] = 'd';
}
if(S_ISCHR(info.st_mode))
{
stmode[0] = 'c';
}
if(S_ISBLK(info.st_mode))
{
stmode[0] = 'b';
}
if(S_ISFIFO(info.st_mode))
{
stmode[0] = 'p';
}
if(S_ISLNK(info.st_mode))
{
stmode[0] = 'l';
}
if(S_ISSOCK(info.st_mode))
{
stmode[0] = 's';
}
/*解析权限位*/
if(info.st_mode & S_IRUSR)
{
stmode[1] = 'r';
}
if(info.st_mode & S_IWUSR)
{
stmode[2] = 'w';
}
if(info.st_mode & S_IXUSR)
{
stmode[3] = 'x';
}
if(info.st_mode & S_IRGRP)
{
stmode[4] = 'r';
}
if(info.st_mode & S_IWGRP)
{
stmode[5] = 'w';
}
if(info.st_mode & S_IXGRP)
{
stmode[6] = 'x';
}
if(info.st_mode & S_IROTH)
{
stmode[7] = 'r';
}
if(info.st_mode & S_IWOTH)
{
stmode[8] = 'w';
}
if(info.st_mode & S_IXOTH)
{
stmode[9] = 'x';
}
stmode[10] = '\0';
printf("%s",stmode);//打印文件类型和文件权限
printf("%ld ", info.st_nlink); //打印硬链接数
usr = getpwuid(info.st_uid);
printf("%s ", usr->pw_name); //打印用户名
gp = getgrgid(info.st_gid);
printf("%s ", gp->gr_name); //打印用户组名
printf("%-8ld ", info.st_size); //打印文件大小
t = localtime(&info.st_mtime);
printf("%d月 %d %02d:%02d ", t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min); //打印最后一次修改文件时间
printf("%s\n", buf->d_name); //打印文件名
}
}
closedir(dir);
return 0;
}