嵌入式应用编程学习-文件类型与stat函数

本文详细介绍了Linux系统中的文件类型,重点讲解了如何使用stat函数获取文件的属性,包括inode节点编号、文件大小、类型、其他用户权限以及时间属性。通过structstat和structtimespec结构体展示了具体操作示例。
摘要由CSDN通过智能技术生成


一、 Linux 系统中的文件类型

Linux 系统下一共分为 7 种文件类型。
(1)普通文件(regular file)在 Linux 系统下是最常见的,譬如文本文件、二进制文件。
(2)目录(directory)就是文件夹,文件夹在 Linux 系统中也是一种文件,是一种特殊文件。
(3)字符设备文件和块设备文件:设备文件(字符设备文件、块设备文件)对应的是硬件设备,在 Linux 系统中,硬件设备会对应到一个设备文件,应用程序通过对设备文件的读写来操控、使用硬件设备,譬如 LCD 显示屏、串口、音频、按键等.。
(4)符号链接文件(link)类似于 Windows 系统中的快捷方式文件。
(5)管道文件(pipe)主要用于进程间通信。
(6)套接字文件(socket)也是一种进程间通信的方式,与管道文件不同的是,它们可以在不同主机上的进
程间通信,实际上就是网络通信。

二、文件属性获取stat函数

2.1 stat函数原型

Linux 下可以使用 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 结构体变量。
返回值:成功返回 0;失败返回-1,并设置 error。

2.2 struct stat 结构体

structstat 是内核定义的一个结构体,这个结构体中的所有元素加起来构成了文件的属性信息。

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; /* 文件状态最后被改变的时间 */
};

2.3 st_mode 变量

st_mode 是 structstat 结构体中的一个成员变量,该变量记录了文件的类型、文件的权限这些信息。

O 对应的 3 个 bit 位用于描述其它用户的权限;
G 对应的 3 个 bit 位用于描述同组用户的权限;
U 对应的 3 个 bit 位用于描述文件所有者的权限;
S 对应的 3 个 bit 位用于描述文件的特殊权限。

在这里插入图片描述
这些 bit 位表达内容与 open 函数的 mode 参数相对应,在 mode 参数中表示权限的宏定义,在这里也是可以使用的,这些宏定义如下(以下数字使用的是八进制方式表示):

S_IRWXU 00700 owner has read, write, and execute permission
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRWXG 00070 group has read, write, and execute permission
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 others (not in group) have read, write, and execute permission
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission

判断文件所有者对该文件是否具有可执行权限,可以通过以下方法测试(假设 st 是 structstat 类
型变量):

if (st.st_mode & S_IXUSR) {
//有权限
} else {
//无权限
}

这里我们重点来看看“文件类型”这 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(管道文件)

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

/* 判断是不是普通文件 */
if ((st.st_mode & S_IFMT) == S_IFREG) {
		//S_IFMT 宏是文件类型字段位掩码:
/* 是 */
}
/* 判断是不是链接文件 */
if ((st.st_mode & S_IFMT) == S_IFLNK) {
/* 是 */
}

2.4 struct timespec 结构体

该结构体定义在<time.h>头文件中,是 Linux 系统中时间相关的结构体.

//struct timespec 结构体
struct timespec
{
 time_t tv_sec; /* 秒 */
 syscall_slong_t tv_nsec; /* 纳秒 */
};

三、使用示例

3.1 获取文件的 inode 节点编号以及文件大小,并将它们打印出来。

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
 struct stat file_stat;
 int ret;
 /* 获取文件属性 */
 ret = stat("./test_file", &file_stat);
 if (-1 == ret) {
 perror("stat error");
 exit(-1);
 }
 /* 打印文件大小和 inode 编号 */
 printf("file size: %ld bytes\n"
 "inode number: %ld\n", file_stat.st_size,
 file_stat.st_ino);
 exit(0);
}

3.2 获取文件的类型,判断此文件对于其它用户(Other)是否具有可读可写权限。

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
 struct stat file_stat;
 int ret;
 /* 获取文件属性 */
 ret = stat("./test_file", &file_stat);
 if (-1 == ret) {
 perror("stat error");
 exit(-1);
 }
 /* 判读文件类型 */
 switch (file_stat.st_mode & S_IFMT) {
 case S_IFSOCK: printf("socket"); break;
 case S_IFLNK: printf("symbolic link"); break;
 case S_IFREG: printf("regular file"); break;
 case S_IFBLK: printf("block device"); break;
 case S_IFDIR: printf("directory"); break;
 case S_IFCHR: printf("character device"); break;
 case S_IFIFO: printf("FIFO"); break;
 }
 printf("\n");
 /* 判断该文件对其它用户是否具有读权限 */
 if (file_stat.st_mode & S_IROTH)
 printf("Read: Yes\n");
 else
 printf("Read: No\n");
 /* 判断该文件对其它用户是否具有写权限 */
 if (file_stat.st_mode & S_IWOTH)
 printf("Write: Yes\n");
 else
 printf("Write: No\n");
  exit(0);
}

3.3 获取文件的时间属性,包括文件最后被访问的时间、文件内容最后被修改的时间以及文件状态最后被改变的时间,并使用字符串形式将其打印出来,包括时间和日期、表示形式自定。

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
 struct stat file_stat;
 struct tm file_tm;
 char time_str[100];
 int ret;
 /* 获取文件属性 */
 ret = stat("./test_file", &file_stat);
 if (-1 == ret) {
 perror("stat error");
 exit(-1);
 }
 /* 打印文件最后被访问的时间 */
 localtime_r(&file_stat.st_atim.tv_sec, &file_tm);
 strftime(time_str, sizeof(time_str),
 "%Y-%m-%d %H:%M:%S", &file_tm);
 printf("time of last access: %s\n", time_str);
 /* 打印文件内容最后被修改的时间 */
 localtime_r(&file_stat.st_mtim.tv_sec, &file_tm);
 strftime(time_str, sizeof(time_str),
 "%Y-%m-%d %H:%M:%S", &file_tm);
 printf("time of last modification: %s\n", time_str);
 /* 打印文件状态最后改变的时间 */
 localtime_r(&file_stat.st_ctim.tv_sec, &file_tm);
 strftime(time_str, sizeof(time_str),
 "%Y-%m-%d %H:%M:%S", &file_tm);
 printf("time of last status change: %s\n", time_str);
 exit(0);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值