文件属性获取 stat

ls -l <文件名>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ls -i <文件名>

查看文件(唯一)的 inode号。
在这里插入图片描述

stat

在这里插入图片描述
在这里插入图片描述

定义 stat 结构体变量

struct stat <变量名>;

stat 函数的使用

int stat(const char *path, struct stat *buf);
功能:获取文件属性
参数:path:文件路径名
      buf:保存文件属性信息的结构体
返回值:成功:0
      失败:-1
    
struct stat {
        dev_t     st_dev;			/* 设备包含文件的ID */
        ino_t     st_ino;     		/* inode号 */
        mode_t    st_mode;    		/* 文件类型和权限 */
        nlink_t   st_nlink;   		/* 硬链接数 */
        uid_t     st_uid;     		/* 用户ID */
        gid_t     st_gid;     		/* 组ID */
        off_t     st_size;    		/* 大小 */
        dev_t     st_rdev;        	/* 设备ID */
        time_t    st_atime;   		/* 最后访问时间 */
        time_t    st_mtime;   		/* 最后修改时间 */
        time_t    st_ctime;  		/* 最后状态改变时间 */
    };

在这里插入图片描述
在这里插入图片描述

if (stat("路径", &结构体变量) < 0){
    perror("提示语句");
    return -1;
}

访问成员变量

在这里插入图片描述

st_mode 与 文件类型

文件类型和权限:st_mode
e.g. 33204(10) ---> 0100664(8)

0100664(8): 
最高两位(不包含八进制标志位0),即 10 两位:
和 S_IFMT 执行按位与操作,可得文件类型

在这里插入图片描述
或直接使用下面的方法来判断文件类型:
在这里插入图片描述
在这里插入图片描述

st_mode 与 rwx 权限

文件类型和权限:st_mode
e.g. 33204(10) ---> 0100664(8)

0100664(8):
第三位(不包含八进制标志位0),即 664 前的 0:见下图
后三位:用户、组用户、其他用户的操作权限

实现 ls - l <文件名> 功能

1)确定文件类型

方法一:

在这里插入图片描述

方法二:

在这里插入图片描述

2)确定三组权限值

在这里插入图片描述
其他两组与之类似。不过,此法可优化:

// 确定三组权限值
char right[3] = "rwx";
for (int i = 0; i < 9; i++)
    (st.st_mode & (0400 >> i)) ? printf("%c", right[i%3]): printf("-");

3)确定硬链接数

printf("%d", 结构体变量名.st_nlink);

4)确定用户名和组名

struct passwd *getpwuid(uid_t uid);
功能:通过用户 id 获取用户属性
参数:uid:用户 id
返回值:返回保存用户相关属性结构体的地址
 失败:NULL
 
struct passwd {
               char   *pw_name;       /* 用户名 */
               char   *pw_passwd;     /* 密码 */
               uid_t   pw_uid;        /* user ID */
               gid_t   pw_gid;        /* group ID */
               char   *pw_gecos;      /* 真实名 */
               char   *pw_dir;        /* 主目录 */
               char   *pw_shell;      /* 使用的shell */
           };
struct group *getgrgid(gid_t gid);
功能:通过组 id 获取组属性
参数:gid:组 id
返回值:返回保存组相关属性结构体的地址 err:NULL

struct group {
               char   *gr_name;        /* 组名 */
               char   *gr_passwd;      /* 组密码 */
               gid_t   gr_gid;         /* 组ID */
               char  **gr_mem;         /*组成员账号 */
           };

在这里插入图片描述

5)确定文件大小

printf("%d", 结构体变量名.st_size);

6)获取最后一次更改时间

char *ctime(const time_t *timep);
功能:将时间秒数转化为字符串表示
参数:timep :时间
返回值:成功返回字符串首地址,失败:NULL

7)*整合实现

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


int main(int argc, char const *argv[])
{
    struct stat st;
    if (stat(argv[1], &st) < 0){
        perror("Failed: ");
        return -1;
    }

    switch (st.st_mode & S_IFMT)
    {
    case S_IFSOCK:
        putchar('s');
        break;
    case S_IFLNK:
        putchar('l');
        break;
    case S_IFREG:
        putchar('-');
        break;
    case S_IFBLK:
        putchar('b');
        break;
    case S_IFCHR:
        putchar('c');
        break;
    case S_IFIFO:
        putchar('p');
        break;
    case S_IFDIR:
        putchar('d');
        break;
    default:
        break;
    }

    if (st.st_mode & S_IRUSR)
        putchar('r');
    else
        putchar('-');
    if (st.st_mode & S_IWUSR)
        putchar('w');
    else
        putchar('-');
    if (st.st_mode & S_IXUSR)
        putchar('x');
    else
        putchar('-');
    
    if (st.st_mode & S_IRGRP)
        putchar('r');
    else
        putchar('-');
    if (st.st_mode & S_IWGRP)
        putchar('w');
    else
        putchar('-');
    if (st.st_mode & S_IXGRP)
        putchar('x');
    else
        putchar('-');

    if (st.st_mode & S_IROTH)
        putchar('r');
    else
        putchar('-');
    if (st.st_mode & S_IWOTH)
        putchar('w');
    else
        putchar('-');
    if (st.st_mode & S_IXOTH)
        putchar('x');
    else
        putchar('-');

    putchar(32);
    printf("%d", st.st_nlink);
    putchar(32);
    printf("%s", getpwuid(st.st_uid)->pw_name);
    putchar(32);
    printf("%s", getgrgid(st.st_gid)->gr_name);
    putchar(32);
    printf("%ld", st.st_size);
    putchar(32);
    printf("%.12s", ctime(&st.st_mtime)+4);
    putchar(32);
    printf("%s", argv[1]);
    putchar(10);

    return 0;
}

switch(st.st_mode & S_IFMT){…} 可作如下替换:
在这里插入图片描述
确定三组权限值可优化:
在这里插入图片描述
运行结果如下:
在这里插入图片描述

实现计时器

编程读写一个文件 test.txt,每隔 1秒 向文件中写入一行数据。
该程序应该无限循环,直到按 Ctrl+C 中断程序。
再次启动程序写文件时可以追加到原文件之后,并且序号能够接续上次的序号.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
    FILE *fp = fopen(argv[1], "a+");
    if (fp == NULL){
        perror("Failed: ");
        return -1;
    }

    char arr[1024] = {};
    int row = 0;

    while (fgets(arr, 1024, fp))
    {
        if (arr[strlen(arr)-1] == '\n')
        row++;
    }

    time_t t;
    struct tm *now;
    
    while (1){

        fprintf(fp, "%d\t", ++row);

        time(&t);

        now = localtime(&t);

        fprintf(fp, "%d-%02d-%02d ", now->tm_year+1900, now->tm_mon+1, now->tm_mday);
        fprintf(fp, "%02d:%02d:%02d \n", now->tm_hour, now->tm_min, now->tm_sec);
        sleep(1);
        fflush(fp);			// 若不加此句,则 缓冲区满 或 程序结束 才打印到文件中
    }
    
    fclose(fp);
    return 0;
}

运行结果如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值