欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Unix环境高级编程 读书笔记 第四章 文件和目录

程序员文章站 2022-05-28 11:02:10
...

函数stat、fstat、fstatat和lstat

这四个函数的原型为:

#include <sys/stat.h>
int stat(const char *restrict pathname, struct stat *restrict buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *restrict pathname, struct stat *restrict buf);
int fstatat(int fd, const char *restrict pathname, struct stat *restrict buf, int flag);
/*若成功,返回0,若出错,返回-1*/

restrict是c99标准引入的,它只可以用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式。即它告诉编译器,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不能通过其它途径(其它变量或指针)来修改;这样做的好处是,能帮助编译器进行更好的优化代码,生成更有效率的汇编代码.如 int *restrict ptr, ptr 指向的内存单元只能被 ptr 访问到,任何同样指向这个内存单元的其他指针都是未定义的,直白点就是无效指针。restrict 的出现是因为 C 语言本身固有的缺陷,C 程序员应当主动地规避这个缺陷,而编译器也会很配合地优化你的代码。

数据结构struct stat的定义随具体的实现有所不同,在GUN C LIB中,结构体的定义为:

struct stat
  {
    __dev_t st_dev;			/* Device.  */
#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
    unsigned short int __pad1;
    __ino_t st_ino;			/* File serial number.	*/
#else
    __ino64_t st_ino;			/* File serial number.	*/
#endif
    __mode_t st_mode;			/* File mode.  */
    __nlink_t st_nlink;			/* Link count.  */
    __uid_t st_uid;			/* User ID of the file's owner.	*/
    __gid_t st_gid;			/* Group ID of the file's group.*/
    __dev_t st_rdev;			/* Device number, if device.  */
    unsigned short int __pad2;
#ifndef __USE_FILE_OFFSET64
    __off_t st_size;			/* Size of file, in bytes.  */
#else
    __off64_t st_size;			/* Size of file, in bytes.  */
#endif
    __blksize_t st_blksize;		/* Optimal block size for I/O.  */

#ifndef __USE_FILE_OFFSET64
    __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */
#else
    __blkcnt64_t st_blocks;		/* Number 512-byte blocks allocated. */
#endif
#ifdef __USE_XOPEN2K8
    /* Nanosecond resolution timestamps are stored in a format
       equivalent to 'struct timespec'.  This is the type used
       whenever possible but the Unix namespace rules do not allow the
       identifier 'timespec' to appear in the <sys/stat.h> header.
       Therefore we have to handle the use of this header in strictly
       standard-compliant sources special.  */
    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
#else
    __time_t st_atime;			/* Time of last access.  */
    unsigned long int st_atimensec;	/* Nscecs of last access.  */
    __time_t st_mtime;			/* Time of last modification.  */
    unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
    __time_t st_ctime;			/* Time of last status change.  */
    unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
#endif
    unsigned long int __glibc_reserved4;
    unsigned long int __glibc_reserved5;
  };

函数stat根据pathname返回与此命名文件有关的信息结构。
函数fstat获取已在描述符fd上打开文件的有关信息结构。
函数lstat类似于stat,但是当命名的文件是一个符号链接时,lstat返回该符号链接的有关信息,而不是符号链接引用的文件信息。
函数fstatat为一个相对于当前打开目录(fd参数指向)的路径名返回文件的信息结构,flag参数控制着是否跟随一个符号链接。如果fd参数是AT_FDCWD,并且pathname是相对路径,则fstatat会计算相对于当前目录的pathname参数,如果pathname是绝对路径,则fd参数将会被忽略。

相关标签: UNIX