stat函数(stat、fstat、lstat)

2023-11-03

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>     //需包含头文件

有如下三个函数的函数原型:

int stat(const char *path, struct stat *buf);

第一个形参:指出文件(文件路径); 第二个形参:出参数(函数对该参数操作,然后传出)。

int fstat(int fd, struct stat *buf);

fstat函数与stat函数的功能一样,只是第一个形参是文件描述符。

int lstat(const char *path, struct stat *buf);

lstat函数的形参跟stat函数的形参一样。其功能也跟stat函数功能一样,仅有一点不同:stat函数是穿透(追踪)函数,即对软链接文件进行操作时,操作的是链接到的那一个文件,不是软链接文件本身;而lstat函数是不穿透(不追踪)函数,对软链接文件进行操作时,操作的是软链接文件本身。

以上三个函数:成功返回0,失败返回-1,并且将详细错误信息赋值给errno全局变量。

其它Linux系统函数类似,带l表示不追踪,不带l表示追踪(穿透)。如:ls –l命令查看的文件属性,是不追踪(不穿透)的;rm删除文件时,是不追踪的;Vi和Vim是穿透的;对于穿透的命令,是无法判断文件是不是软链接文件,比如ls –l命令,其是不穿透的,因此可以判断是否是软链接文件;如果是用stat函数实现的ls –l命令,则是穿透的,对于查看原文件和链接文件的属性是一样的,无法区别两者,因此可以考虑用lstat函数来实现ls –l命令的功能。

注意:创建软链接最好用绝对路径  ln –s 原文件 软链接文件(采用绝对路径)

statlstatfstat函数中 struct stat类型的说明:

struct stat {

               dev_t     st_dev;     /* 文件的设备编号 */

               ino_t     st_ino;     /* 索引结点编号 */

               mode_t    st_mode;    /* 文件类型和权限*/

               nlink_t   st_nlink;   /*硬链接数 */

               uid_t     st_uid;     /*用户ID*/

               gid_t     st_gid;     /* ID*/

               dev_t     st_rdev;    /* 设备类型(若此文件为设备文件,则为设备编号*/

               off_t      st_size;    /* 文件大小*/

               blksize_t   st_blksize; /*文件系统的I/O缓冲区大小*/

               blkcnt_t   st_blocks;  /* 块数 */

               time_t    st_atime;   /* 访问时间 */

               time_t    st_mtime;   /* 修改时间 */

               time_t    st_ctime;   /* 更改时间 */

         };  //标红为重点内容

struct stat结构体位于inode(索引结点)中,但是其内部不包含文件名。文件名位于位于文件的目录项dentry中(即简化的FCB),其包含文件名和inode编号。通过denty的inode编号可以找到inode,进一步找到文件本身。硬链接就是denty(目录项)。

上述结构体中,对st_mode成员做一个详细的介绍:

mode_t    st_mode;    /* 文件类型和权限*/

st_mode变量(mode_t类型):该变量占 2byte共16位,为16位的整型值。用于储存文件类型和权限。 如下图所示:

每一位均为二进制数。r代表4,即100;w代表2,即010;x代表1,即001。由于总共16位二进制数,因此需要6位8进制数来进行表示,其中8进制数以0开头,共7位。

其他人权限(0~2位)。读权限:0000004,在所给函数头文件中进行了宏定义为:S_IROTH;写:0000002,S_IWOTH;执行:0000001,S_IXOTH。 掩码为:0000007,S_IRWXO  掩码的作用:st_mode & 掩码 就可以过滤st_mode中除其他人权限以外的信息,所得结果直接是其他人的权限信息,下面原理相同。

所属组权限(3~5位)。读权限:0000040, S_IRGRP;写:0000020,S_IWGRP;执行:0000010,S_IXGRP。 掩码为:0000070,S_IRWXG。

所属主权限(6~8位)。读权限:0000400, S_IRUSR;写:0000200,S_IWUSR;执行:0000100,S_IXUSR。 掩码为:0000700,S_IRWXU。

特殊权限位(9~11位)。SUID:0004000, S_ISUID;SGID:0002000,S_ISGID;SBIT:0001000,S_ISVTX。 //特殊权限位很少用

文件类型(12~15位,共7种类型文件)。套接字(socket)文件s:0140000,S_IFSOCK;链接文件(软链接)l:0120000,S_IFLNK;普通文件-:0100000,S_IFREG;块设备文件b:0060000,S_IFBLK;目录文件d:0040000,S_IFDIR;字符设备文件c:0020000,S_IFCHR;管道文件p:0010000,S_IFIFO。    掩码:0170000  作用一样,st_mode & 掩码 的结果与七种类型的宏相比较,就可以判断是哪一种文件。

强调一下特殊权限位SBIT(粘滞位)的功能:1.对目录设置粘滞位,则该目录内的文件只能被文件所有者、超级用户和目录所有者这三类用户删除,其他用户都没有删除的权限;2.对文件设置了粘滞位,那么在内存资源十分紧张的情况下,也不会把该文件放回到磁盘上。如磁盘的对换区SWAP,当内存紧张,优先级别低的进程会被暂时放回到对换区中,但是一旦设置了粘滞位,则不会放回磁盘,依然处于内存。

下面是说明stat函数的使用的代码:

//运用stat函数实现查看文件大小属性的功能

[root@localhost work]# vim statuse.c

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main( int argc,char *argv[ ] )   //命令行参数
{
    if( argc < 2 )
    printf("./statuse filename1 filename2 ...\n");

    struct stat zsx;
    int ret;
    int i=1;
    for( i=1;i<argc;i++ )
    {
        ret = stat( argv[i],&zsx);   //stat函数获取文件的属性,穿透的
        if( ret == -1 )
        {
            perror("stat filename");
            exit(1);
        }

        int size = (int)zsx.st_size;   //注意,必须强制转换,后者变量是off_t类型
        printf("%s      %d\n",argv[i],size);
    }

    return 0;
}

[root@localhost work]# gcc -pipe -ggdb3 -pedantic -Wall statuse.c -o statuse

[root@localhost work]# ls

english.txt  ls-l.c  stat.c  statuse  statuse.c

[root@localhost work]# ./statuse english.txt ls-l.c stat.c statuse statuse.c

english.txt      109055

ls-l.c       2204

stat.c       416

statuse     57468

statuse.c  535

 [root@localhost work]# ll english.txt

-rwxrwxrwx. 1 root root 109055 Mar 19 10:30 english.txt

//运用stat函数实现ls –l 命令的功能

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


int main(int argc, char* argv[])
{
    if(argc < 2)


int main(int argc, char* argv[])
{
    if(argc < 2)
    {
        printf("./a.out filename\n");
        exit(1);
    }

    struct stat st;
    int ret = stat(argv[1], &st);
    if(ret == -1)
    {
        perror("stat");
        exit(1);
    }

    // 存储文件类型和访问权限
    char perms[11] = {0};
    // 判断文件类型
    switch(st.st_mode & S_IFMT)
    {
        case S_IFLNK:
            perms[0] = 'l';
            break;
        case S_IFDIR:
            perms[0] = 'd';
            break;
        case S_IFREG:
            perms[0] = '-';
            break;
        case S_IFBLK:
            perms[0] = 'b';
            break;
        case S_IFCHR:
            perms[0] = 'c';
            break;
        case S_IFSOCK:
            perms[0] = 's';
            break;
        case S_IFIFO:
            perms[0] = 'p';
            break;
        default:
            perms[0] = '?';
            break;
    }
    // 判断文件的访问权限
    // 文件所有者
    perms[1] = (st.st_mode & S_IRUSR) ? 'r' : '-';
    perms[2] = (st.st_mode & S_IWUSR) ? 'w' : '-';
    perms[3] = (st.st_mode & S_IXUSR) ? 'x' : '-';
    // 文件所属组
    perms[4] = (st.st_mode & S_IRGRP) ? 'r' : '-';
    perms[5] = (st.st_mode & S_IWGRP) ? 'w' : '-';
    perms[6] = (st.st_mode & S_IXGRP) ? 'x' : '-';
    // 其他人
    perms[7] = (st.st_mode & S_IROTH) ? 'r' : '-';
    perms[8] = (st.st_mode & S_IWOTH) ? 'w' : '-';
    perms[9] = (st.st_mode & S_IXOTH) ? 'x' : '-';

    // 硬链接计数
    int linkNum = st.st_nlink;
    // 文件所有者
    char* fileUser = getpwuid(st.st_uid)->pw_name;
    // 文件所属组
    char* fileGrp = getgrgid(st.st_gid)->gr_name;
    // 文件大小
    int fileSize = (int)st.st_size;
    // 修改时间
    char* time = ctime(&st.st_mtime);
    char mtime[512] = {0};
    strncpy(mtime, time, strlen(time)-1);

    char buf[1024];
    sprintf(buf, "%s  %d  %s  %s  %d  %s  %s", perms, linkNum, fileUser, fileGrp, fileSize, mtime, argv[1]);

    printf("%s\n", buf);

    return 0;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

stat函数(stat、fstat、lstat) 的相关文章

  • C#中unsafe的使用

    1 unsafe在C 程序中的使用场合 实时应用 采用指针来提高性能 引用非 net DLL提供的如C 编写的外部函数 需要指针来传递该函数 调试 用以检测程序在运行过程中的内存使用状况 2 使用unsafe的利弊 好处是 性能和灵活性提高
  • fastcgi的环境变量

    FCGI ROLE RESPONDER SCRIPT FILENAME scripts 5 cgi QUERY STRING aaa 11111111111111 bbb 2222222222222222 ccc 3333333333333
  • C++知识积累:内存对齐理解

    为什么要进行内存对齐 这是因为CPU的读取总是对齐的 举个例子 假设CPU是32位的 那么CPU每次读取的4字节数据的首地址都是4的倍数 也就是说 内存中数据首地址为4的倍数时 CPU一次操作就可以完成数据读取 假设有一个int型四字节大小
  • [原]Pro*C介绍-内嵌SQL

    Translate by Z Jingwei Document address http www db stanford edu ullman fcdb oracle or proc html Pro C介绍内嵌SQL 概要 Pro C语法
  • Qt5学习之路(vs2012下创建一个QT应用程序)2013-10-14

    刚开始学习QT在网上找的资料基本都是使用QT Create进行开发的 VS下开发的学习资料感觉很少很难找的到 视频教程也基本没看到过貌似 因为我们研发中心是使用MFC进行开发开发工具是VS2010 使用QT开发的话基本我们不会再使用QT C
  • 多线程系列之——事件内核对象

    所有内核对象里面事件内核对象是最简单的一个 它包括一个使用计数 还有两个布尔值 一个布尔值用来表示事件是手动重置事件还是自动重置事件 另一个布尔值表示当前是否处于触发状态 当一个手动重置事件被触发的时候 所有等待该事件的线程都能变成调度状态
  • C++工程师复习题

    一 auto ptr 类使用必须满足下列限制 1 不要使用 auto ptr 对象保存指向静态分配对象的指针 2 不要使用两个 auto ptrs 对象指向同一对象 3 不要使用 auto ptr 对象保存指向动态分配数组的指针 4 不要将
  • 写时拷贝技术(copy-on-write)

    传统的fork 系统调用直接把所有的资源复制给新创建的进程 这种实现过于简单并且效率低下 因为它拷贝的数据也许并不共享 更糟的情况是 如果新进程打算立即执行一个新的映像 那么所有的拷贝都将前功尽弃 Linux的fork 使用写时拷贝 cop
  • c++得到窗口句柄

    include
  • 无法打开源文件<sys/time.h>,但是用time.h编译就会出错,缺少gettimeofday()

    因为sys time h是uinx系统下的库文件 而现在使用的平台是在windows 由于未指明程序运行的系统 导致找不到对应的头文件 需要重新实现gettimeofday 函数 define WIN32 include
  • vector,list,deque区别

    http blog csdn net renkaihao article details 6803866 vector和built in数组类似 它拥有一段连续的内存空间 并且起始地址不变 因此它能非常好的支持随即存取 即 操作符 但由于它
  • c语言判断一个数是否为偶数

    include
  • R----dplyr包介绍学习

    dplyr包 plyr包的替代者 专门面对数据框 将ddplyr转变为更易用的接口 gt 来自dplyr包的管道函数 其作用是将前一步的结果直接传参给下一步的函数 从而省略了中间的赋值步骤 可以大量减少内存中的对象 节省内存 可惜的是应用范
  • Open3D(C++)实现建筑物点云立面和平面分割提取

    Open3D C 实现建筑物点云立面和平面分割提取 近年来 点云技术在城市规划 机器人地图构建等领域得到广泛应用 本篇文章将介绍如何利用Open3D C 库实现建筑物点云立面和平面分割提取 准备工作 首先需要编译安装Open3D库 本文使用
  • visual studio 一直显示正在准备解决方案

    首先重启电脑 无法解决的情况下执行以下步骤 Kill Visual Studio Open Visual Studio without loading a solution Disable AnkhSvn as Source Control
  • Java反序列化漏洞-CC1利用链分析

    文章目录 一 前置知识 1 反射 2 Commons Collections是什么 3 环境准备 二 分析利用链 1 Transform
  • C/C++编程中的算法实现技巧与案例分析

    C C 编程语言因其高效 灵活和底层的特性 被广大开发者用于实现各种复杂算法 本文将通过10个具体的算法案例 详细探讨C C 在算法实现中的技巧和应用 一 冒泡排序 Bubble Sort 冒泡排序 Bubble Sort 是一种简单的排序
  • 在 OS X 上的 virtualenv 中安装 scrapy 加密时发生错误 [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我正在安装 scrapypip in virtualenv on OS X 10 11 当它安装密码学时 它说 buil
  • 在 Solaris 上,使用 gcc 编译的库与使用 cc 生成的库的使用方式是否相同?

    我目前正在尝试编译 libxml2在 Solaris 上 当我运行源代码提供的 configure 脚本时 会自动使用 gcc 和 g 编译器 但是 我想使用 cc 和 CC 编译器 所以我跑 configure CC cc CXX CC
  • Woocommerce:添加第二个电子邮件地址不起作用,除非收件人是管理员

    我尝试了多种方法来向 Woocommerce 电子邮件添加其他收件人 但它似乎仅适用于主要收件人是管理员的测试订单 这些是我尝试过的片段 如果订单的客户是管理员 则电子邮件将发送到这两个地址 如果订单包含客户电子邮件地址 则仅发送至该电子邮

随机推荐

  • ERP让员工和企业双赢

    企业的科学管理 离不开数字化 而数字化 就需要企业积累数据 这就离不开ERP ERP实施 如果只是员工增加了数据录入量 而没有获得实际的益处 比如 效率提高 难度降低等 则员工内心会抵制ERP 员工要的是方便 企业要的是数据 必须兼顾二者
  • 快速理解聚集索引和非聚集索引

    数据库的索引 听起来挺神秘的 仔细想想 这些索引 其实就是平时咱们查东西时候常用的两种手段 无非就是为了提高我们找东西的效率而已 那么我们平时又是怎么查东西呢 聚集索引 聚集索引 来源于生活尝试 这中索引可以说是按照数据的物理存储进行划分的
  • 工作中遇到的数据库死锁问题 - 排查方案 CannotAcquireLockException

    问题 重现 正常情况下 销售人员在使用我们的销售系统为客户创建订单时候 后台java代码就会开启事务 然后往数据库中添加订单信息和订单详情信息 以及一些其他业务操作 但由于某次异常操作 可能是网络或者其他的原因 导出系统出现问题无法工作 于
  • Font Awesome矢量版,十六进制版,WPF字体使用

    Font Awesome为您提供可缩放的矢量图标 您可以使用CSS所提供的所有特性对它们进行更改 包括 大小 颜色 阴影或者其它任何支持的效果 WPF可以使用FontAwesome字体 Android可以使用FontAwesome字体 需要
  • python小游戏毕设 接金币小游戏设计与实现 (源码)

    文章目录 1 项目简介 1 游戏介绍 2 实现效果 3 开发工具 3 1 环境配置 3 2 Pygame介绍 4 具体实现 5 最后 1 项目简介 Hi 各位同学好呀 这里是L学长 今天向大家分享一个今年 2022 最新完成的毕业设计项目作
  • 【华为OD机试真题】日志采集系统(python)100%通过率 超详细代码注释 代码优化

    华为OD机试真题 2022 2023 真题目录 点这里 华为OD机试真题 信号发射和接收 试读 点这里 华为OD机试真题 租车骑绿道 试读 点这里 日志采集系统 时间限制 1s空间限制 256MB限定语言 不限 题目描述 日志采集是运维系统
  • 【Android】BottomNavigationView+ViewPager实现底部导航栏(步骤+源码)

    吐糟大会 时隔好久再一次在博客上与大家见面 上一年九月份怀疑自己不适合这行毅然辞职 我没结婚没车贷没房贷本以为能很潇洒 但现实给我开了个玩笑 我发现除了这一行其他什么都不会 也许是我很懒吧 为了能吃饱饭我再次踏入这一行 回归初衷为了让更多刚
  • RDF与可视化

    Rudolf RDFViz Exploring tools for RDF Graph Visualisation http www ilrt bris ac uk discovery rdf dev rudolf rdfviz To vi
  • Win10系统无法打开chm文档提示无法显示该页面怎么办?

    网上下载了一个chm文档 但打开后发现无法显示该页 提示 确保 Web 地址 ieframe dll dnserrordiagoff htm 正确 通过查找相关资料 迅速了解决该问题 特此分享 一 CHM文档定义 CHM Compiled
  • 查看电脑CPU是否支持虚拟化

    有两次方法 使用securable 可以在一下地址下载https www grc com files securable exe 安装双击就会出现如图 32 64 就是表示电脑的位数 D E P 表示的是硬件 Virtualization表
  • VSCode 下python输出中文乱码问题

    在处理这个问题之前 你首先得知道为什么会出现这个这个问题 你在使用VScode编辑代码时 代码页面中文正常 而终端输出那里中文却为乱码 出现这个现象的原因是因为编码方式的不同 VScode的默认编码方式为UTF 8 中国地区下cmd的编码方
  • github下载的项目如何build--如何利用configure.ac和Makefile.am,生成Makefile。

    环境是Ubuntu18 04 1 aclocal命令根据configure ac文件的内容 自动生成aclocal m4文件 2 autoconf命令会根据configure ac和aclocal m4文件 生成configure文件 3
  • 基于 Flutter+Dart 聊天实例

    1 项目介绍 Flutter是目前比较流行的跨平台开发技术 凭借其出色的性能获得很多前端技术爱好者的关注 比如阿里闲鱼 美团 腾讯等大公司都有投入相关案例生产使用 flutter chatroom项目是基于Flutter Dart chew
  • TortoiseGit 入门指南11:还原与重置

    Git 就像个时光机器 能让我们还原到任何提交 还原未提交的更改 假如我们在查看一个干净的代码仓库 干净意味着工作区中的文件保持着最后一次提交的状态 没有修改 在查看的过程中 我们有意或无意的修改了工作区中的文件 之后我们想把这些文件恢复成
  • STLINK-V3 STDC14座转2.54mm排针转接板Kicad工程

    简介 这是一个 STLINK V3 STDC14座转2 54mm排针转接板Kicad工程 STDC14座实际工作中不太方便 所以搞了这个转接板 另外转接版上提供了可选的电源输出功能 An adapter board for STLINK V
  • EMC测试仪器_EMC测试整改流程及常见问题

    EMC主要是通过测试产品在电磁方面的干扰大小和抗干扰能力的综合评定 是产品在质量安全认证重要的指标之一 很多产品在做产品安全认证时都会遇到产品测试不合格的情况 尤其是在电磁兼容测试 即EMC测试 出错频率更是普遍 当产品一旦测试不合格 那么
  • J-002 Jetson电路设计之电源设计--NANO && XAVIER NX

    Jetson电源设计 1 电源说明 1 1 电源和系统引脚描述 1 2 电源控制框图详情 2 上电的时许 2 1 框图分析 2 2 上电时序 3 GND引脚 1 电源说明 Jetson NANO和XAVIER NX核心板的电源为DC 5V
  • 白盒测试之静态检查

    态检查一般是检查编码标准规范 错误列表 编码规范往往团队 会根据自己的经验和风格进行设置一些规范 现在很多IDE工具都会 在编辑代码的时候实时的提醒是否符合代码风格 错误列表 一般 是代码潜在的bug 由于某种代码写法虽然没有语法错误 但是
  • 现在有多个异步操作ajax请求,我们需要当所有异步请求都成功的时候,执行后续操作

    1 场景 现在有多个异步操作ajax请求 我们需要当所有异步请求都成功的时候 执行后续操作 2 方法 方法一 通常的讲 我们可以设置一个flag变量 然后在各自的ajax的成功回调内去维护这个变量数量 当满足条件时 我们来触发后续函数 方法
  • stat函数(stat、fstat、lstat)

    include