嵌入式Linux系统编程 — 3.2 stat、fstat 和 lstat 函数查看文件属性

目录

1 文件有哪些属性

2 stat函数

2.1 stat函数简介

2.2 struct stat 结构体

2.3 struct timespec 结构体

2.4 示例程序

3  fstat 和 lstat 函数

3.1 fstat 函数

3.2 lstat 函数


1 文件有哪些属性

Linux文件属性是对文件和目录的元数据描述,包括文件类型、权限设置、所有者、所属组、文件大小、修改时间、状态更改时间、访问时间、inode号、链接数以及文件系统等,这些属性通过命令如ls -lstat可以查看,它们定义了文件的访问权限和存储细节,是Linux系统管理文件的基础。

2 stat函数

2.1 stat函数简介

Linux 下可以使用 stat 命令查看文件的属性,命令内部就是通过调用 stat()函数来获取文件属性的, stat 函数是 Linux 中的系统调用,用于获取文件相关的信息,函数原型如下所示(可通过"man 2 stat"命令查看) :

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>int stat(const char *pathname, struct stat *buf);

pathname: 用于指定一个需要查看属性的文件路径。
buf: struct stat 类型指针,用于指向一个 struct stat 结构体变量。调用 stat 函数的时候需要传入一个 structstat 变量的指针, 获取到的文件属性信息就记录在 struct stat 结构体中,结构体含义见2.2节。
返回值: 成功返回 0;失败返回-1,并设置 error。

2.2 struct stat 结构体

struct stat结构体用于存储由stat()系统调用返回的文件信息,在<sys/stat.h>头文件中申明,结构体内容如下所示:

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; /* 设备号(指针对设备文件) */off_t st_size; /* 文件大小(以字节为单位) */blksize_t st_blksize; /* 文件内容存储的块大小 */blkcnt_t st_blocks; /* 文件内容所占块数 */struct timespec st_atim; /* 文件最后被访问的时间 */struct timespec st_mtim; /* 文件内容最后被修改的时间 */struct timespec st_ctim; /* 文件状态最后被改变的时间 */
};

关于st_mode参数可参考文章4.1节:嵌入式Linux系统编程 — 1.1 文件I/O基础-CSDN博客

t_mode参数中包含“文件类型”,“文件类型”用4 个 bit 位表示,并有相应的宏定义, 这 4 个 bit 位用于描述该文件的类型,譬如该文件是普通文件、还是链接文件、亦或者是一个目录等,那么就可以通过这 4 个 bit 位数据判断出来,如下所示:

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(管道文件)

上面这些数字使用的是八进制方式来表示的,在 C 语言中,八进制方式表示一个数字需要在数字前面添加一个 0。所以由上面可知,当“文件类型”这 4 个 bit 位对应的数字是 14(八进制)时,表
示该文件是一个套接字文件。

所以通过 st_mode 变量可以判断文件类型,如下(假设 st 是 struct stat 类型变量) :

/* 判断是不是普通文件 */
if ((st.st_mode & S_IFMT) == S_IFREG) {/* 是 */
}
/* 判断是不是链接文件 */
if ((st.st_mode & S_IFMT) == S_IFLNK) {/* 是 */
}

除了这样判断之外,我们还可以使用 Linux 系统封装好的宏来进行判断,如下所示(m 是 st_mode变量) :

S_ISREG(m) #判断是不是普通文件,如果是返回 true,否则返回 false
S_ISDIR(m) #判断是不是目录,如果是返回 true,否则返回 false
S_ISCHR(m) #判断是不是字符设备文件,如果是返回 true,否则返回 false
S_ISBLK(m) #判断是不是块设备文件,如果是返回 true,否则返回 false
S_ISFIFO(m) #判断是不是管道文件,如果是返回 true,否则返回 false
S_ISLNK(m) #判断是不是链接文件,如果是返回 true,否则返回 false
S_ISSOCK(m) #判断是不是套接字文件,如果是返回 true,否则返回 false

有了这些宏之后,就可以通过如下方式来判断文件类型了:

/* 判断是不是普通文件 */
if (S_ISREG(st.st_mode)) {/* 是 */
}/* 判断是不是目录 */
if (S_ISDIR(st.st_mode)) {/* 是 */
}

2.3 struct timespec 结构体

该结构体定义在<time.h>头文件中, 是 Linux 系统中时间相关的结构体,结构体内容如下所示:

struct timespec
{time_t tv_sec; /* 秒 */syscall_slong_t tv_nsec; /* 纳秒 */
};
  • tv_sec:表示自1970年1月1日(UTC时间)以来的秒数,这是一个time_t类型的值。
  • tv_nsec:表示tv_sec之后的纳秒数,范围从0到999,999,999。这个字段用于提供比秒更精确的时间度量。

2.4 示例程序

下面的代码通过命令行接收一个文件名作为参数,并使用stat系统调用来获取该文件的状态信息。

#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>// 函数用于将time_t类型的时间转换为可读的字符串格式并打印
void print_time(time_t time) {struct tm *tm_info; // 用于存储本地时间信息的结构体char buffer[26];    // 用于存储格式化时间的字符串tm_info = localtime(&time); // 将time_t转换为本地时间strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info); // 格式化时间printf("%s\n", buffer); // 打印格式化后的时间字符串
}int main(int argc, char *argv[]) {struct stat file_stat; // 用于存储文件状态的结构体// 检查命令行参数数量,确保有文件名提供if (argc < 2) {printf("Usage: %s <filename>\n", argv[0]);return 1;}// 使用stat系统调用来获取文件状态if (stat(argv[1], &file_stat) == -1) {perror("Error getting file status"); // 打印错误信息return 1;}// 打印文件的inode节点编号和文件大小printf("Inode: %ld\n", (long)file_stat.st_ino);printf("Size: %lld bytes\n", (long long)file_stat.st_size);// 判断文件类型并打印switch (file_stat.st_mode & S_IFMT) {case S_IFREG:printf("Regular file\n");break;case S_IFDIR:printf("Directory\n");break;// 可以添加更多的文件类型判断default:printf("Unknown type\n");}// 检查其他用户的权限if (file_stat.st_mode & S_IROTH && file_stat.st_mode & S_IWOTH)printf("Other users have read and write permissions\n");elseprintf("Other users do not have read and write permissions\n");// 打印文件的时间属性printf("Last accessed: ");print_time(file_stat.st_atime);printf("Last modified: ");print_time(file_stat.st_mtime);printf("Status was last changed: ");print_time(file_stat.st_ctime);printf("\n");return 0;
}

程序定义了一个print_time函数,用于将time_t类型的时间戳转换为易读的日期和时间字符串格式,并将其打印出来。在main函数中,首先检查是否提供了足够的命令行参数,然后获取文件状态,打印文件的inode编号、大小、类型以及其他用户的读写权限。最后,程序调用print_time函数打印文件的最后访问时间、最后修改时间和状态最后改变时间。程序运行结果如下:

3  fstat 和 lstat 函数

3.1 fstat 函数

除了 stat 函数之外,还可以使用 fstat 和 lstat 两个系统调用来获取文件属性信息。

fstat 与 stat 区别在于, stat 是从文件名出发得到文件属性信息,不需要先打开文件;而 fstat 函数则是从文件描述符出发得到文件属性信息,所以使用 fstat 函数之前需要先打开文件得到文件描述符。

#include <sys/stat.h>
#include <unistd.h>int fstat(int filedes, struct stat *buf);
  • filedes:指定要获取状态的文件描述符。
  • buf:指向一个 struct stat 结构体的指针,该结构体用于接收文件的状态信息。

fstat 函数使用示例如下:

#include <stdio.h>
#include <sys/stat.h>int main() {FILE *file = fopen("example.txt", "w"); // 使用标准I/O库打开文件if (file == NULL) {perror("Failed to open file");return 1;}struct stat file_stat;if (fstat(fileno(file), &file_stat) == -1) { // 使用文件流获取文件描述符并获取状态信息perror("Failed to get file status");fclose(file);return 1;}printf("File size: %lld bytes\n", (long long)file_stat.st_size);fclose(file); // 使用标准I/O库关闭文件return 0;
}

代码使用 fstat 函数通过 fopen 得到的文件流获取文件状态信息,包括文件大小。然后,它打印出文件的大小。运行结果如下:

3.2 lstat 函数

lstat()与 stat、 fstat 的区别在于,对于符号链接文件, stat、 fstat 查阅的是符号链接文件所指向的文件对应的文件属性信息,而 lstat 查阅的是符号链接文件本身的属性信息。lstat 函数原型如下所示:

#include <sys/stat.h>
#include <unistd.h>int lstat(const char *path, struct stat *buf);
  • path:指定要获取状态的文件或链接的路径。
  • buf:指向一个 struct stat 结构体的指针,该结构体用于接收文件或链接的状态信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/850311.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

30-unittest生成测试报告(HTMLTestRunner插件)

批量执行完测试用例后&#xff0c;为了更好的展示测试报告&#xff0c;最好是生成HTML格式的。本文使用第三方HTMLTestRunner插件生成测试报告。 一、导入HTMLTestRunner模块 这个模块下载不能通过pip安装&#xff0c;只能下载后手动导入&#xff0c;下载地址是&#xff1a;ht…

应用广义线性模型一|线性模型

文章目录 一、统计学及思维模式二、未知现象的数学描述三、线性模型&#xff08;一&#xff09;线性模型的定义&#xff08;二&#xff09;线性模型的参数估计&#xff08;三&#xff09;线性模型的应用&#xff08;四&#xff09;离散解释变量的设计向量构建方法 四、线性模型…

SpringAOP 常见应用场景

文章目录 SpringAOP1 概念2 常见应用场景3 AOP的几种通知类型分别有什么常见的应用场景4 AOP实现 性能监控4.1 首先&#xff0c;定义一个切面类&#xff0c;用于实现性能监控逻辑&#xff1a;4.2 定义自定义注解4.3 注解修饰监控的方法 5 AOP实现 API调用统计5.1 定义切面类&am…

深度图的方法实现加雾,Synscapes数据集以及D455相机拍摄为例

前言 在次之前&#xff0c;我们已经做了图像加雾的一些研究&#xff0c;这里我们将从深度图的方法实现加雾展开细讲 图像加雾算法的研究与应用_图像加雾 算法-CSDN博客 接下来将要介绍如何使用深度图像生成雾效图像的方法。利用Synscapes数据集&#xff0c;通过读取EXR格式的…

【实盘】第二十期:2024-06月~第一周

一、每周净值 01 CTA投资组合 CTA多品种全覆盖全天候策略2024年2月至2024年5月底实盘总收益12.753%&#xff0c;当前浮动净值为1.1407&#xff0c;当前平仓净值为1.12753。 月度最大本金回撤0.3%(资金曲线为平仓盈亏,总体回撤应加入浮动持仓的盈亏总体计算,实际当前净值见棕色…

各种空气能热泵安装图

空气能热泵安装图 循环式空气能热泵安装图 直热循环式空气能热泵安装图 泳池空气能热泵安装图 循环式水源热泵热安装系统原理图 直热循环式水源热泵安装系统图 空气水源热泵安装图

flutter as连接网易模拟器

网易模拟器下载 Mac 使用MuMu模拟器调试 Flutter开发 Android Studio 安装第三方模拟器—网易MuMu Mac 安卓Studio使用外部模拟器 Mac电脑&#xff1a;Android Studio 连接 MUMU 网易模拟器 Mac 上 Android Studio 链接网易 MuMu 模拟器调试 在 .zshrc 中设置 adb 二进制文…

重构某测试站点

一、计算校验值 校验值结果&#xff1a; 文件名称&#xff1a;培训用centos.rar&#xff0c;文件大小&#xff1a;1,335,759,953&#xff0c;MD5&#xff1a;534EC38CDA7DA2196C84AC8F6092514B&#xff0c;SHA1&#xff1a;FD35D86A27A007AE10872980C48653A110DF6067&#xf…

EverWeb 强大的零基础Mac网页设计制作软件

搜索Mac软件之家下载EverWeb 强大的零基础Mac网页设计制作软件 EverWeb 4.2是非专业网页设计师的绝佳网页制作工具&#xff0c;无需编码即可创建美观、响应迅速的网站。只需拖放自己的图像、文本和其他任何html元素到网页布局的任何位置。 EverWeb的功能特性&#xff1a; 下…

C++模板编程—学习C++类库的编程基础

课程总目录 文章目录 一、详解函数模板二、类模板三、类模板实践&#xff1a;实现向量容器vector四、理解容器空间配置器allocator的重要性 一、详解函数模板 模板的意义&#xff1a;对类型也可以进行参数化了 // 也可以用template<class T>&#xff0c;但class容易和类…

适用于 Windows 的 8 大数据恢复软件

数据恢复软件可帮助您恢复因意外删除或由于某些技术故障&#xff08;如硬盘损坏等&#xff09;而丢失的数据。这些工具可帮助您从硬盘驱动器 (HDD) 中高效地恢复丢失的数据&#xff0c;因为这些工具不支持从 SSD 恢复数据。重要的是要了解&#xff0c;您删除的数据不会被系统永…

NodeJs实现脚本:将xlxs文件输出到json文件中

文章目录 前期工作和依赖笔记功能代码输出 最近有一个功能&#xff0c;将json文件里的内容抽取到一个xlxs中&#xff0c;然后维护xlxs文件。当要更新json文件时&#xff0c;就更新xlxs的内容并把它传回json中。这个脚本主要使用NodeJS写。 以下是完成此功能时做的一些笔记。 …

【面试八股总结】内存页面置换算法

参考资料&#xff1a;小林coding、阿秀 缺页中断 在 CPU 里访问一条 Load M 指令&#xff0c;然后 CPU 会去找 M 所对应的页表项。如果该页表项的状态位是「有效的」&#xff0c;那 CPU 就可以直接去访问物理内存了&#xff0c;如果状态位是「无效的」&#xff0c;则 CPU 则会…

stanfordcorenlp+python做中文nlp任务,得到的结果中全是空字符串,而不是中文字符串

问题描述 代码&#xff1a; from stanfordcorenlp import StanfordCoreNLP import logging#中文中的应用&#xff0c;一定记得下载中文jar包&#xff0c;并标志lang‘zh’ nlp_zh StanfordCoreNLP(rD:\stanford-corenlp-full-2016-10-31, port8094, langzh,quietFalse,logg…

GiantPandaCV | 提升分类模型acc(一):BatchSizeLARS

本文来源公众号“GiantPandaCV”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;提升分类模型acc(一)&#xff1a;BatchSize&LARS 在使用大的bs训练情况下&#xff0c;会对精度有一定程度的损失&#xff0c;本文探讨了训练的b…

Java Web学习笔记24——Vue项目开发流程

import是引入文件。 export是将对象导出为模块。 new Vue({ router, router: h > h(App) }).$mount(#app) App.vue: vue的组成文件以.vue结尾&#xff0c;每个组件由三个部分组成&#xff1a;<template>、<script>、<style>。 <template><d…

i.MX8MP平台开发分享(RDC软件配置篇)

Uboot中已经将RDC的配置写入到了OCRAM中&#xff0c;NXP在ATF中预设了SIP服务&#xff0c;SIP服务下有厂商自定义的smc命令ID。例如下面的DDR、GPC、SRC和HAB的smc回调函数。 在SRC中断处理函数中&#xff0c;对于SRC_M4_START指令&#xff0c;先读取OCRAM中的配置&#xff0c;…

第一个小爬虫_爬取 股票数据

前言 爬取 雪球网的股票数据 [环境使用]&#xff1a;python 3.12 解释器pycharm 编辑器 【模块使用】&#xff1a;import requests -->数据请求模块 要安装 命令 pip install requestsimport csv -->将数据保存到CSV表格中import pandas -->也可以将数据保…

vue3+vite插件开发

插件开发目的:由于我司使用的前端技术栈为vue3tsvite2.Xaxios,在前端代码框架设计初期,做了把axios挂载到proxy对象上的操作,具体可见我的另一篇文章vue3TS自动化封装全局api_ts 封装腾讯位置api-CSDN博客 现在可以实现vue2的类似this.$api.xxx去调用接口,但是vue2源码使用的是…

flutter日历范围选择器

1.传入日期跨度&#xff0c;选择上架日期时&#xff0c;自动显示下架日期 2.手动选择上架日期和下架日期(图中下架日期自动填了只需CalendarDateRangePicker在initState方法中使用_startDate widget.initialStartDate; _endDate widget.initialEndDate;&#xff0c;而不直接…