Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >stat()函数_stat函数返回值

stat()函数_stat函数返回值

作者头像
全栈程序员站长
发布于 2022-09-24 05:58:15
发布于 2022-09-24 05:58:15
3.7K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

在 linux 中,经常需要获取文件的属性,比如修改时间,文件大小等等。stat 函数将会帮助我们得到这些信息。

1 stat 函数

1.1 stat 函数的作用

linux 中,可以使用 stat 函数来获取文件相关的信息,就比如说文件的大小文件的类型等等。

1.2 struct stat 结构体

stat 函数将获取到的结果保存到一个名为 struct stat 的结构体中。它的样子如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 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 */
    dev_t     st_rdev;        /* 设备ID */
    off_t     st_size;        /* 文件占用的字节数 */
    blksize_t st_blksize;     /* 文件系统块大小 */
    blkcnt_t  st_blocks;      /* 文件占用了几个512字节 */
    time_t    st_atime;       /* 最后访问时间 */
    time_t    st_mtime;       /* 最后更改时间 */
    time_t    st_ctime;       /* 最后状态更改时间 */
};

1.3 stat 函数原型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int stat(const char *pathname, struct stat *buf);

stat 函数的第一个参数是目标文件的路径。第二个参数是输出参数,用来保存返回的文件信息的结果。

stat 函数的返回值如果是 0,表示函数执行成功,否则失败。失败后会改写 errno 这个全局变量。我们可以使用 perror 这个函数打印失败的原因。

2 实验

  • 代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// filename: statdemo.c

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

int main() {
  struct stat st; 
  int r = stat("test.txt", &st);
  if (r) {
    perror("stat");
    return -1; 
  }

  printf("st_dev = %lld\n", st.st_dev);
  printf("st_ino = %ld\n", st.st_ino);
  printf("st_mode = %d\n", st.st_mode);
  printf("st_nlink = %d\n", st.st_nlink);
  printf("st_uid = %d\n", st.st_uid);
  printf("st_gid = %d\n", st.st_gid);
  printf("st_size = %ld\n", st.st_size);

  printf("st_atime = %ld\n", st.st_atime);
  printf("st_mtime = %ld\n", st.st_mtime);
  printf("st_ctime = %ld\n", st.st_ctime);
  return 0;
}
  • 编译
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gcc statdemo.c -o st
  • 运行结果

如果 test.txt 文件不存在,打印如下结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
stat: No such file or directory

如果 test.txt 文件存在,其内容只包含 hello 5 个字符,打印结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
st_dev = 2049
st_ino = 831785
st_mode = 33204
st_nlink = 1
st_uid = 1000
st_gid = 1000
st_size = 6 // 这个结果是 6 是因为 vim 编辑器会自动在最后一个字符后面插入一个 '\n' 字符
st_atime = 1480252548
st_mtime = 1480252548
st_ctime = 1480252548

从以上结果可以看到文件信息各个字段的的内容。比如最近访问时间,最近更改时间,最近状态更改时间等等。还有访问权限位(st_mode)等等。另外需要注意的是,文件的类型也可以从 st_mode 中得出,这些我们将在后面介绍。

3 更加深入

掌握了 stat 函数的用法,相信你不应该止步于此。我们提出的问题是,stat 函数是从哪儿获取到文件信息的?

倘若你阅读了前面几篇有关文件系统的章节,相信你还回忆得起 目录项inode 节点 这些很重要的名词。

3.1 再理一遍文件查找过程

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cur_inode = 2
for name in path: // 分析路径中的每一层次的名称
    if isLeaf(name): // 如果是最后一级目录,退出
        break
    for dir_entry in cur_inode.dir_entries: // 遍历当前 inode 节点中的每一个目录项
        if dir_entry.name == name: // 根据路径中某一层次的名称找到目录项
            if dir_entry.file_type == EXT2_FT_DIR: // 判断是是否是目录
                cur_inode = dir_entry.inode // 更新当前 inode 节点
                continue
        else:
            break
return cur_inode // 到这里就已经找到了 当前文件的 inode 编号,即 cur_inode。

3.2 相关结构体

  • dir_entry 结构体如下:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct ext2_dir_entry_2 {
    __u32   inode;          /* Inode number */
    __u16   rec_len;        /* Directory entry length */
    __u8    name_len;       /* Name length */
    __u8    file_type;
    char    name[EXT2_NAME_LEN];    /* File name */
};
  • inode 节点结构体如下:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct ext2_inode {
    __u16   i_mode;     /* File mode */
    __u16   i_uid;      /* Low 16 bits of Owner Uid */
    __u32   i_size;     /* Size in bytes */
    __u32   i_atime;    /* Access time */
    __u32   i_ctime;    /* Creation time */
    __u32   i_mtime;    /* Modification time */
    __u32   i_dtime;    /* Deletion Time */
    __u16   i_gid;      /* Low 16 bits of Group Id */
    __u16   i_links_count;  /* Links count */
    __u32   i_blocks;   /* Blocks count */
    __u32   i_flags;    /* File flags */
    union {
        struct {
            __u32  l_i_reserved1;
        } linux1;
        struct {
            __u32  h_i_translator;
        } hurd1;
        struct {
            __u32  m_i_reserved1;
        } masix1;
    } osd1;             /* OS dependent 1 */
    __u32   i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
    __u32   i_generation;   /* File version (for NFS) */
    __u32   i_file_acl; /* File ACL */
    __u32   i_dir_acl;  /* Directory ACL */
    __u32   i_faddr;    /* Fragment address */
    union {
        struct {
            __u8    l_i_frag;   /* Fragment number */
            __u8    l_i_fsize;  /* Fragment size */
            __u16   i_pad1;
            __u16   l_i_uid_high;   /* these 2 fields */
            __u16   l_i_gid_high;   /* were reserved2[0] */
            __u32   l_i_reserved2;
        } linux2;
        struct {
            __u8    h_i_frag;   /* Fragment number */
            __u8    h_i_fsize;  /* Fragment size */
            __u16   h_i_mode_high;
            __u16   h_i_uid_high;
            __u16   h_i_gid_high;
            __u32   h_i_author;
        } hurd2;
        struct {
            __u8    m_i_frag;   /* Fragment number */
            __u8    m_i_fsize;  /* Fragment size */
            __u16   m_pad1;
            __u32   m_i_reserved2[2];
        } masix2;
    } osd2;             /* OS dependent 2 */
};

3.3 stat 是如何找到文件信息的?

参考 3.1 中的文件查找流程,stat 可以很容易的从 inode 结构体中获取。比如 st_mode 字段来源于 inode 的 i_mode 字段等等。

需要注意的是,作为用户态程序,你是无法直接读取磁盘的,这也导致了我们没有办法自己去解析磁盘数据。这是出于操作系统安全角度考虑的,如果你不小心破坏了文件系统,这将直接导致操作系统无法启动。

linux 并不直接提供你操作磁盘的方法,除非你自己写 linux 驱动程序。但是为了让你获取一些必要的信息,linux 提供了一些接口给你使用,比如这里的 stat 函数。

4 小结

本节你需要掌握 stat 函数,并打印出这些整数值。关于这些整数如何转换成人类可读的,后面将一一介绍。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/171778.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
带你全面了解 Flutter,它好在哪里?它的坑在哪里? 应该怎么学?
回顾了这段时间解答关于 Flutter 的各种问题后,我突然发现很多刚刚接触 Flutter 的萌新,对于 Flutter 都有着不同程度的误解,而每次重复的解释又十分浪费时间,最终我还是决定写篇文章来做个总结。
GSYTech
2021/03/02
1.8K0
带你全面了解 Flutter,它好在哪里?它的坑在哪里? 应该怎么学?
革命性web前端框架Flutter详细介绍和学习路径
Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。
Javanx
2019/09/04
4K0
革命性web前端框架Flutter详细介绍和学习路径
Flutter 开发实战与前景展望 - RTC Dev Meetup
大家好,我是郭树煜,Github GSY 系列开源项目的作者,系列包括有 GSYVideoPlayer 、GSYGitGithubApp(Flutter\ReactNative\Kotlin\Weex)四大版本,目前总 star 在 17 k+ 左右,主要活跃在掘金社区,id 是恋猫的小郭,主要专栏有《Flutter完整开发实战详解》系列等,平时工作负责移动端项目的开发,工作经历从 Android 到 React Native 、Weex 再到如今的 Flutter ,期间也参与过 React 、 Vue 、小程序等相关的开发,算是一个大前端的选手吧。
GSYTech
2019/05/26
2K0
全网最全 Flutter 与 React Native 深入对比分析
作为 GSY 开源系列的作者,在去年也整理过 《移动端跨平台开发的深度解析》 的对比文章,时隔一年之后,本篇将重新由 环境搭建、实现原理、编程开发、插件开发、编译运行、性能稳定、发展未来 等七个方面,对当前的 React Native 和 Flutter 进行全面的分析对比,希望能给你更有价值的参考。
GSYTech
2019/06/21
7.8K1
全网最全 Flutter 与 React Native 深入对比分析
Android开发:手把手带你入门跨平台UI开发框架Flutter
Flutter理念:“一切皆为Widget”,Widget是Flutter应用程序用户界面的基本构建块,具备以下特点:
Android技术干货分享
2019/07/28
1.4K0
热门跨平台方案对比:WEEX、React Native、Flutter和PWA
本文主要对WEEX、React Native、Flutter和PWA几大热门跨平台方案进行简单的介绍和对比。内容选自《WEEX跨平台开发实战》 (WEEX项目负责人力荐,从入门到实战,教你玩转移动前端跨平台开发!)
博文视点Broadview
2020/06/10
4.4K0
热门跨平台方案对比:WEEX、React Native、Flutter和PWA
再谈移动端跨平台框架 Flutter 与 React Native
这几年在大前端的开发领域,选择跨端方案的公司和部门越来越多,一方面是跨平台的前端框架越来越成熟,另一方面也是因原生开发者正逐年减少。所以,在当下掌握一门跨平台的技术栈还是很有必要的,无论从广度还是从深度都会有所帮助。
做个快乐的码农
2021/12/29
2.2K0
再谈移动端跨平台框架 Flutter 与 React Native
Carson带你学Android:手把手带你入门跨平台UI开发框架Flutter
Flutter理念:“一切皆为Widget”,Widget是Flutter应用程序用户界面的基本构建块,具备以下特点:
Carson.Ho
2022/03/24
8310
Carson带你学Android:手把手带你入门跨平台UI开发框架Flutter
给 Android 和 iOS 开发人员不一样的 Flutter 基础讲解
了解 Flutter 之前,首先介绍一个简单基础知识点,那就是大部分的移动端跨平台框架都是“单页面”应用。
GSYTech
2021/04/28
1.6K0
给 Android 和 iOS 开发人员不一样的 Flutter 基础讲解
最火移动端跨平台方案盘点:React Native、weex、Flutter
跨平台一直是老生常谈的话题,cordova、ionic、react-native、weex、kotlin-native、flutter等跨平台框架的百花齐放,颇有一股推倒原生开发者的势头。
JackJiang
2018/08/13
7.5K0
最火移动端跨平台方案盘点:React Native、weex、Flutter
5000字解析:前端五种跨平台技术
本文不涉及到任何代码,只讲概念层面的,结合本人在实际开发过程中的各种体验,对这几种跨平台技术进行一个点评。
凡泰极客
2020/03/30
1.4K0
5000字解析:前端五种跨平台技术
2022 年 Flutter 适合我吗?Flutter VS Other 量化对比
Hello 大家好,我是《Flutter 开发实战详解》的作者,Github GSY 系列开源项目的负责人郭树煜,比如 gsy_github_app_flutter 、GSYVideoPlayer 等的项目 。
GSYTech
2022/04/25
4.1K0
2022 年 Flutter 适合我吗?Flutter VS Other 量化对比
移动端跨平台开发的深度解析
 跨平台一直是老生常谈的话题,cordova、ionic、react-native、weex、kotlin-native、flutter等跨平台框架的百花齐放,颇有一股推倒原生开发者的势头。(事实上更多是共存发展)看完本篇,相信你会对于当下跨平台移动开发的现状、实现原理、框架的选择等有更深入的理解。
GSYTech
2018/08/11
3.5K0
移动端跨平台开发的深度解析
浅谈跨平台框架 Flutter 的优势与结构
目前,移动开发技术主要分为原生开发和跨平台开发两种。其中,原生应用是指在某个特定的移动平台上,使用平台所支持的开发工具和语言,直接调用系统提供的API所开发的应用。
个推
2019/03/22
2.8K0
浅谈跨平台框架 Flutter 的优势与结构
移动跨平台框架Flutter详细介绍和学习线路分享
Flutter是一款移动应用程序SDK,一份代码可以同时生成iOS和Android两个高性能、高保真的应用程序。 Flutter目标是使开发人员能够交付在不同平台上都感觉自然流畅的高性能应用程序。我们兼容滚动行为、排版、图标等方面的差异。 在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。
Android技术干货分享
2019/07/18
2.1K0
移动跨平台框架Flutter详细介绍和学习线路分享
跨平台技术演进及Flutter未来
移动互联网发展十余年,伴随着 Android、iOS 等智能手机的不断普及,移动端已逐步取代 PC 端,成为兵家必争之地。正所谓“得移动端者得天下”,移动端已成为互联网领域最大的流量分发入口,一大批互联网公司正是在这大趋势下崛起。
程序亦非猿
2019/11/09
2.1K0
跨平台技术演进及Flutter未来
5000字解析:前端五种跨平台技术
本文不涉及到任何代码,只讲概念层面的,结合本人在实际开发过程中的各种体验,对这几种跨平台技术进行一个点评
Peter谭金杰
2020/05/09
1.3K0
5000字解析:前端五种跨平台技术
大前端开发中的路由管理之三:Android篇
        我们通常认为Android开发中的路由管理主要分为两部分,Android原生页面栈和混合开发页面栈。在native原生页面中,使用最多的是四大组件之一的Activity和依托于其的Fragment。在混合开发页面中,通常又分为Activity-H5(WebView),Activity-Weex/React-Native,和Activity-Flutter这几种跨平台的页面交互方式。 1、原生之Activity的页面跳转与管理 1.1 从Activity启动模式入手         在An
QQ音乐技术团队
2021/11/10
3.5K0
《Flutter》-- 1.Flutter简介
第一类是使用原生内置浏览器加载HTML5的Hybrid技术方案,采用此类方案的主要有Cordova、ionic和微信小程序;
爱学习的程序媛
2022/04/07
1.4K0
《Flutter》-- 1.Flutter简介
移动跨平台技术方案总结
“得移动端者得天下”,移动端取代PC端,成为了互联网行业最大的流量分发入口,因此不少公司制定了“移动优先”的发展策略。
xiangzhihong
2020/01/14
2.7K0
移动跨平台技术方案总结
推荐阅读
相关推荐
带你全面了解 Flutter,它好在哪里?它的坑在哪里? 应该怎么学?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验