大家好,我是练习编程时长两年半的个人练习生昆工第一ikun,今天我们来分享一下目录文件的操作,并实现“ls -l”功能的实现,话不多说,上代码!!
目录
一、目录操作
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]; /*文件名*/ };
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 } 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
二、实现ls -l命令功能
我们都知道Linux Ubuntu下有一个命令“ls -l”可以查看文件的类型、权限、硬链接数、用户名、用户组名、大小、更新时间、文件名。如下图:
那么我们能不能自己编写一个程序来实现这个功能呢,那就要用到今天分享的目录操作,我们来看代码。
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <time.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
int main(int argc, char *argv[])
{
DIR *dir = opendir(".");
if(dir == NULL)
{
perror("opendir");
return -1;
}
struct dirent *read = NULL;
struct stat s;
struct tm *t = NULL;
struct passwd *uid = NULL;
struct group *gid = NULL;
char str[4] = {'x','w', 'r', '-'};
while((read = readdir(dir)) != NULL)
{
if(read->d_name[0] != '.')
{
lstat(read->d_name, &s);
switch(s.st_mode & S_IFMT)
{
case S_IFSOCK:
printf("s");
break;
case S_IFLNK:
printf("l");
break;
case S_IFREG:
printf("-");
break;
case S_IFBLK:
printf("b");
break;
case S_IFDIR:
printf("d");
break;
case S_IFCHR:
printf("c");
break;
case S_IFIFO:
printf("p");
break;
}
for(int i = 8; i >= 0; i--)
{
if(s.st_mode & 1 << i)
{
printf("%c", str[i%3]);
}
else
{
printf("%c", str[3]);
}
}
printf("%4ld ", s.st_nlink);
uid = getpwuid(s.st_uid);
printf("%2s ", uid->pw_name);
gid = getgrgid(s.st_gid);
printf("%2s ", gid->gr_name);
printf("%-8ld ", s.st_size);
t = localtime(&s.st_mtime);
printf("%d月 %2d %2d:%d ", t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min);
printf("%-8s ", read->d_name);
printf("\n");
}
}
closedir(dir);
return 0;
}
运行代码,我们可以实现和“ls -l”命令一样的功能,如下图:
本文含有隐藏内容,请 开通VIP 后查看