Linux 下完成 ls-l 的功能

ls -l:

farsight@ubuntu:~/px/IO进线程/dir$ ls -l
total 24
-rwxrwxr-x 1 farsight farsight 7599  8月 25 05:16 a.out
-rw-rw-r-- 1 farsight farsight 2797  8月 25 05:16 lstat.c
-rw-rw-r-- 1 farsight farsight 2797  8月 25 05:15 lstat.c~
-rw-rw-r-- 1 farsight farsight  535  8月 10 05:21 opendir.c
-rw-rw-r-- 1 farsight farsight  692  8月 10 05:34 readdir.c

 获取文件属性 --- lstat()

相关结构体为:

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_mtim,tv_sec
}

getgrgid--得到用户组名的函数
getpwuid--得到用户名的函数 

由该函数的结构体可知,硬连接数、用户名、用户组名、文件大小、文件名都可以直接获得,修改文件的时间则需借助 locatime 函数获取,比较复杂的就是获取文件类型和文件权限了。

下面分别分析文件类型和文件权限的获取方法:

(1)文件类型的获取

获取文件类型对应有一下宏:

        S_IFMT   0170000   bit mask for the file type bit filed --- 文件类型掩码   

        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_TFMT 等于对应文件类型宏,则文件类型宏对应类型就为文件类型

(2) 文件权限的获取

用户权限

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
        
判断方法:  

st_mode & 对应权限宏  ==  宏本身 表示具有该权限

如果直接用 if 来判断,虽然直观,但是麻烦,这里可以用循环左移依次与对应权限宏相与,例如:左移8位、5位、2位,都对应写权限,左移7位、4位、1位:执行权限

代码:

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <grp.h>
#include <pwd.h>


int main()
{
	int ret = 0;
	int i;
	int x = 1;	
	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;
			}

			switch(info.st_mode & S_IFMT)
			{
				case S_IFREG:
					printf("-");//普通文件
					break;
				case S_IFDIR:
					printf("d");//目录文件
					break;
				case S_IFSOCK:
					printf("s");//套接字
					break;
				case S_IFLNK:
					printf("l");//链接文件
					break;
				case S_IFBLK:
					printf("b");//块设备文件
					break;
				case S_IFIFO:
					printf("p");//管道文件
					break;
				case S_IFCHR:
					printf("c");//字符设备文件
					break;
			}
			
			for(i = 8; i >= 0; i--)
			{
				if(info.st_mode & (x << i))//x左移i位
				{
					switch(i%3)
					{
						case 2:
							printf("r");//第8、5、2位都是r权限
							break;
						case 1:
							printf("w");//第7、4、1位都是r权限
							break;
						case 0:
							printf("x");//第6、3、0位都是r权限
							break;
					}
				}
				else
				{
					printf("-");//没有权限
				}
			}
			
			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;
}
farsight@ubuntu:~/dir$ ./a.out
-rw-rw-r--  1  farsight  farsight  2797     8月  25  05:16  lstat.c~
-rw-rw-r--  1  farsight  farsight  692      8月  10  05:34  readdir.c
-rwxrwxr-x  1  farsight  farsight  7599     8月  8  08:17  a.out
-rw-rw-r--  1  farsight  farsight  2797     8月  26  01:47  lstat.c
-rw-rw-r--  1  farsight  farsight  535      8月  10  05:21  opendir.c

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值