前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >stat函数

stat函数

作者头像
zy010101
发布2019-08-01 15:23:27
1.9K0
发布2019-08-01 15:23:27
举报
文章被收录于专栏:程序员程序员

stat函数可以给出文件的性质,也可以直接在shell下输入命令:stat 文件名。

我们可以看的文件的相关信息。 然后我们查看stat这个函数。使用man 2 stat。

其中参数statbuf是一个结构体指针。这个结构体中包含的成员如下:

文件类型信息包含在stat结构的st_mode成员中。这个成员的大小是2字节。它还包含了文件的权限信息。他的位结构如下:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

0-2位:表示的是其他人的权限;

3-5位:表示的是文件所在组权限;

6-8位:表示的是文件拥有者的权限。

9-11位:特殊权限位。

12-15位:表示文件类型。

早期的Unix系统并没有提供S_ISxxx这样的宏来提取文件类型,我们只好使用屏蔽字S_IFMT(0170000)来进行按位与运算,这样就能提取到文件的类型。当然,提取文件权限的时候也可以使用类似的屏蔽字。

这个结构体中定义的宏是为了兼容性,2008年标准以前的时间都是time_t类型的(以秒来计),timespec则提供了更高精度的时间戳,为了保持兼容性,使用了宏定义将旧的名字定义为了tv_sec成员。

stat的成员st_size表示的是以字节为单位的文件长度,这个字段只对普通文件,目录文件和符号链接有用。对于Linux系统的普通文件,他的大小可以是0字节,例如用touch命令创建一个空文件,它的大小就是0.在Linux系统下,目录文件的大小总是4Kb。符号链接文件的大小表示的是原文件的文件名长度(包括路径长度)。例如:

以上使用的是UTF-8编码,故一般一个汉字占据3字节。所以总长度是24.

stat函数是一个穿透函数,它在读软链接的时候,会将软链接指向的文件的实际信息读取出来,而不是读取软链接本身的文件信息;而lstat函数不穿透,它就是读取软链接本身的文件信息。

下面仿照ls -l命令来基本实现一下该命令。使用lstat函数。

代码语言:javascript
复制
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char * argv[])
{
    struct stat buf;        //存放文件信息
    char file_type;         //文件类型
    char file_mode[9] = {'-','-','-','-','-','-','-','-','-'};      //文件权限
    int file_hardlink;      //硬链接数
    char uid[10]={0};       //文件拥有者
    char gid[10]={0};       //文件所在组
    int file_size;          //文件大小
    time_t file_lasttime;   //最后一次修改时间
    char *name;             //文件名

    lstat(argv[1],&buf);      //获取文件信息
    
    if (S_ISREG(buf.st_mode))       //普通文件
    {
        file_type = '-';
    }
    else if(S_ISDIR(buf.st_mode))       //目录文件
    {
       file_type = 'd';
    }
    else if(S_ISCHR(buf.st_mode))       //字符设备文件
    {
       file_type = 'c';
    }
    else if(S_ISBLK(buf.st_mode))       //块设备文件
    {
       file_type = 'b';
    }
    else if(S_ISFIFO(buf.st_mode))       //管道文件
    {
       file_type = 'p';
    }
    else if(S_ISLNK(buf.st_mode))       //链接文件
    {
       file_type = 'l';
    }

    if(buf.st_mode & S_IRUSR)
    {
        file_mode[0] = 'r';
    }
    if(buf.st_mode & S_IWUSR)
    {
        file_mode[1] = 'w';
    }
    if (buf.st_mode & S_IXUSR)
    {
        file_mode[2] = 'x';
    }
    if (buf.st_mode & S_IROTH)
    {
        file_mode[6] = 'r';
    }
    if (buf.st_mode & S_IWOTH)
    {
        file_mode[7] = 'w';
    }
    if (buf.st_mode & S_IXOTH)
    {
        file_mode[8] = 'x';
    }
    if (buf.st_mode & S_IWGRP)
    {
        file_mode[3] = 'r';
    }
    if (buf.st_mode & S_IRGRP)
    {
        file_mode[4] = 'w';
    }
    if (buf.st_mode & S_IXGRP)
    {
        file_mode[5] = 'x';
    }
    
    file_hardlink = buf.st_nlink;       //硬链接数

    if(buf.st_gid == 1000)
    {
        strcpy(gid,"zy");
    }
    else if (0 == buf.st_gid)
    {
        strcpy(gid,"root");
    }
    
    if(1000 == buf.st_uid)
    {
        strcpy(uid,"zy");
    }
    else if (0 == buf.st_uid)
    {
       strcpy(uid,"root");
    }
    
    file_size = buf.st_size;
    
    name = argv[1];

    printf("%c",file_type);
    for(int i = 0; i < 9; i++)
    {
        printf("%c",file_mode[i]);
    }
    printf(" %d",file_hardlink);
    printf(" %s",uid);
    printf(" %s",gid);
    printf(" %d",file_size);
    printf(" %s\n",name);

    return 0;
}

运行结果如下:

在这个实现中,除了时间,其余的都实现了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年07月19日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档