注:不管用什么调用函数,都记得加上查看man手册时的头文件
1、打开、关闭目录–opendir/closedir
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
参数:目录名
返回值:
成功返回目录流指针,失败返回NULL;
---------------------------------------------------------
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
参数:dirp:目录流指针
返回值:
成功返回目录名,失败返回NULL;
2、读取目录–readdir
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
struct dirent {
char d_name[256]; /* Null-terminated filename */
};
3、获取文件属性–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);
参数:
返回值:
成功返回0,失败返回-1
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* Inode number */
mode_t st_mode; /* File type and mode */
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; /* Block size for filesystem I/O */
blkcnt_t st_blocks; /* Number of 512B blocks allocated */
}
getgrgid--得到用户组名的函数
getpwuid--得到用户名的函数
获取文件类型:
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
4、练习—接下来我们用一个实例来练习对目录的操作:
对目录进行操作获取ls信息:就是用目录调用函数来实现ls -l的效果
这是ls的终端显示:
我们来看看函数的实现,基本上用到了我们所有目录函数的调用:
```c
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <grp.h>
#include <pwd.h>
int main(int argc, char *argv[])
{
DIR *opd=opendir(".");//打开当前目录,'.'也可以换成其他路径的目录
//定义需要用到的结构体,具体可以查看man手册
struct dirent *buf=NULL;
struct stat arr;
struct tm *t;
struct group *gp;
struct passwd *pd;
int ret,ret1;
char typef[10]={0};//定义判断文件类型及其权限的缓冲区
if(NULL==opd)
{
perror("opendir");
return -1;
}
while((buf=readdir(opd))!=NULL)//读取目录,为空才结束
{
if(buf->d_name[0]!='.')//不显示隐藏文件
{
lstat(buf->d_name,&arr);//获取文件名
if(ret1<0)
{
perror("lstat");
return -1;
}
switch(arr.st_mode & S_IFMT)//st_mode & 对应权限宏 ==宏本身 表示具有该权限
{
case S_IFREG:typef[0]='-';//普通文件
break;
case S_IFLNK:typef[0]='l';//链接文件
break;
case S_IFDIR:typef[0]='d';//目录文件
break;
case S_IFBLK:typef[0]='b';//块设备文件
break;
case S_IFIFO:typef[0]='p';//管道文件
break;
case S_IFCHR:typef[0]='c';//字符设备文件
break;
case S_IFSOCK:typef[0]='s';//套接字文件
break;
default:break;
}
//用户(ower)权限
typef[1]=(arr.st_mode & S_IRUSR)?'r':'-';
typef[2]=(arr.st_mode & S_IWUSR)?'w':'-';
typef[3]=(arr.st_mode & S_IXUSR)?'x':'-';
//组(group)权限
typef[4]=(arr.st_mode & S_IRUSR)?'r':'-';
typef[5]=(arr.st_mode & S_IWUSR)?'w':'-';
typef[6]=(arr.st_mode & S_IXUSR)?'x':'-';
//其他(other)权限
typef[7]=(arr.st_mode & S_IRUSR)?'r':'-';
typef[8]=(arr.st_mode & S_IWUSR)?'w':'-';
typef[9]=(arr.st_mode & S_IXUSR)?'x':'-';
printf("%-14s ",buf->d_name);
printf("%s",typef);
printf(" ");
printf("%ld ",arr.st_nlink);//链接文件数
pd=getpwuid(arr.st_uid);//用户名
gp=getgrgid(arr.st_gid);//用户组名
printf("%s ",gp->gr_name);
printf("%s ",pd->pw_name);
printf("%-8ld",arr.st_size);//文件大小
t=localtime(&arr.st_mtime);//获取时间
printf("%d月 %d %d:%d\n",t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min);//定义自己想要的时间格式
}
}
puts("");
ret=closedir(opd);//关闭目录
if(ret<0)
{
perror("closedir");
return -1;
}
return 0;
}
看看代码终端的显示效果:
这样就能实现ls -l的效果了,甚至还能根据自己的喜好需求,增加、删除其他的内容,调正输出的一些格式尺寸。