博客主页:https://blog.csdn.net/wkd_007 螺博客内容螺:嵌入式开发、Linux、C语言、C++、数据结构、音视频 藍本文内容藍:介绍Linux下获取文件元数据的几个函数 | stat、fstat、lstat 金句分享:你不能选择最好的,但最好的会来选择你——泰戈尔

本文未经允许,不得转发!!!

目录

一、概述二、stat 函数三、fstat 函数四、lstat 函数五、总结

一、概述

文件的元数据包含了一些描述文件的信息,包括文件的访问权限、 上次访问的时间戳、 所有者、 所有组、 文件大小等信息。 本文将介绍获取文件元数据的几个函数:stat、fstat、lstat。 首先看一下获取文件元数据的结构体:

struct stat {

dev_t st_dev; /* ID of device containing file */

ino_t st_ino; /* Inode number */

mode_t st_mode; /* File type and mode */

nlink_t st_nlink; /* Number of hard links */

uid_t st_uid; /* User ID of owner */

gid_t st_gid; /* Group ID of owner */

dev_t st_rdev; /* Device ID (if special file) */

off_t st_size; /* Total size, in bytes */

blksize_t st_blksize; /* Block size for filesystem I/O */

blkcnt_t st_blocks; /* Number of 512B blocks allocated */

/* Since Linux 2.6, the kernel supports nanosecond

precision for the following timestamp fields.

For the details before Linux 2.6, see NOTES. */

struct timespec st_atim; /* Time of last access */

struct timespec st_mtim; /* Time of last modification */

struct timespec st_ctim; /* Time of last status change */

#define st_atime st_atim.tv_sec /* Backward compatibility */

#define st_mtime st_mtim.tv_sec

#define st_ctime st_ctim.tv_sec

};

结构体成员就不逐个解释了,可以看看英文注释。值得一提的是,在Linux内核版本2.6之后,struct stat结构体支持纳秒级别时间了,使用了成员st_atim、st_mtim、st_ctim代替了旧的成员st_atime、st_mtime、st_ctime。

还有一点需要注意:st_mode字段可以通过下面宏来判断文件类型:

S_ISREG(m) is it a regular file?

S_ISDIR(m) directory?

S_ISCHR(m) character device?

S_ISBLK(m) block device?

S_ISFIFO(m) FIFO (named pipe)?

S_ISLNK(m) symbolic link? (Not in POSIX.1-1996.)

S_ISSOCK(m) socket? (Not in POSIX.1-1996.)

下面这些宏定义了 st_mode 字段各个文件类型的bit位

S_IFMT 0170000 bit mask for the file type bit fields

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

S_ISUID 0004000 set-user-ID bit

S_ISGID 0002000 set-group-ID bit (see below)

S_ISVTX 0001000 sticky bit (see below)

S_IRWXU 00700 mask for file owner permissions

S_IRUSR 00400 owner has read permission

S_IWUSR 00200 owner has write permission

S_IXUSR 00100 owner has execute permission

S_IRWXG 00070 mask for group permissions

S_IRGRP 00040 group has read permission

S_IWGRP 00020 group has write permission

S_IXGRP 00010 group has execute permission

S_IRWXO 00007 mask for permissions for others (not in group)

S_IROTH 00004 others have read permission

S_IWOTH 00002 others have write permission

S_IXOTH 00001 others have execute permission

二、stat 函数

stat 函数原型:

#include

#include

#include

int stat(const char *pathname, struct stat *statbuf);

成功返回0;失败返回-1

stat 函数根据pathname路径的文件名,通过statbuf参数返回此文件的信息结构。 参数:

pathname:文件路径名称,输入参数statbuf:struct stat结构信息指针,输出参数、

看例子:

#include

#include

#include

#include

int main()

{

struct stat s = {0};

int res = stat("a.txt", &s);//s会被填满

if(res == -1)

{

perror("stat");

return -1;

}

printf("inode: %d\n", (int)(s.st_ino));

printf("读写权限:%#o\n", s.st_mode & 0777);

printf("file size %d\n", (int)(s.st_size));

printf("%lu \n",s.st_atim.tv_nsec);

if(S_ISREG(s.st_mode))

{

printf("普通文件");

}

else if(S_ISDIR(s.st_mode))

{

printf("目录文件");

}

else if(S_ISLNK(s.st_mode))

{

printf("软链接文件");

}

printf("\n");

return 0;

}

保存代码后编译,然后在当前目录通过touch a.txt创建一个a.txt,然后运行。

三、fstat 函数

fstat 函数原型:

#include

#include

#include

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

成功返回0;失败返回-1

fstat 函数根据已打开的fd文件描述符,通过statbuf参数返回此文件的信息结构。 参数:

fd:已打开的fd文件描述符,输入参数statbuf:struct stat结构信息指针,输出参数、

看例子:

#include

#include

#include

#include

#include

int main()

{

struct stat s = {0};

int fd = open("a.txt", O_RDWR | O_CREAT | O_TRUNC, 0664);

int res = fstat(fd, &s);//s会被填满

if(res == -1)

{

perror("stat");

return -1;

}

printf("inode: %d\n", (int)(s.st_ino));

printf("读写权限:%#o\n", s.st_mode & 0777);

printf("file size %d\n", (int)(s.st_size));

printf("%lu \n",s.st_atim.tv_nsec);

if(S_ISREG(s.st_mode))

{

printf("普通文件");

}

else if(S_ISDIR(s.st_mode))

{

printf("目录文件");

}

else if(S_ISLNK(s.st_mode))

{

printf("软链接文件");

}

printf("\n");

return 0;

}

四、lstat 函数

lstat 函数原型:

#include

#include

#include

int lstat(const char *pathname, struct stat *statbuf);

成功返回0;失败返回-1

lstat 函数类似于stat,但是当命名的文件是一个符号链接时,lstat返回该符号链接的有关信息,而不是由该符号链接引用的文件的信息。 参数:

path:文件路径名称,输入参数buf:struct stat结构信息指针,输出参数、

看例子:

#include

#include

#include

#include

#include

#include

int main(int argc, char *argv[])

{

struct stat sb;

if (argc != 2) {

fprintf(stderr, "Usage: %s \n", argv[0]);

exit(EXIT_FAILURE);

}

if (lstat(argv[1], &sb) == -1) {

perror("lstat");

exit(EXIT_FAILURE);

}

printf("ID of containing device: [%lx,%lx]\n",

(long) major(sb.st_dev), (long) minor(sb.st_dev));

printf("File type: ");

switch (sb.st_mode & S_IFMT) {

case S_IFBLK: printf("block device\n"); break;

case S_IFCHR: printf("character device\n"); break;

case S_IFDIR: printf("directory\n"); break;

case S_IFIFO: printf("FIFO/pipe\n"); break;

case S_IFLNK: printf("symlink\n"); break;

case S_IFREG: printf("regular file\n"); break;

case S_IFSOCK: printf("socket\n"); break;

default: printf("unknown?\n"); break;

}

printf("I-node number: %ld\n", (long) sb.st_ino);

printf("Mode: %lo (octal)\n",

(unsigned long) sb.st_mode);

printf("Link count: %ld\n", (long) sb.st_nlink);

printf("Ownership: UID=%ld GID=%ld\n",

(long) sb.st_uid, (long) sb.st_gid);

printf("Preferred I/O block size: %ld bytes\n",

(long) sb.st_blksize);

printf("File size: %lld bytes\n",

(long long) sb.st_size);

printf("Blocks allocated: %lld\n",

(long long) sb.st_blocks);

printf("Last status change: %s", ctime(&sb.st_ctime));

printf("Last file access: %s", ctime(&sb.st_atime));

printf("Last file modification: %s", ctime(&sb.st_mtime));

exit(EXIT_SUCCESS);

}

上面的代码调用lstat,并在返回的stat结构中显示选定的字段。

五、总结

本文介绍了struct stat结构体,以及获取文件元数据的几个函数 :stat、fstat、lstat。

如果文章有帮助的话,点赞、收藏⭐,支持一波,谢谢 

文章链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。