当前位置: 代码迷 >> 综合 >> linux 查看文件属性stat fstat fstatat lstat
  详细解决方案

linux 查看文件属性stat fstat fstatat lstat

热度:95   发布时间:2023-09-06 12:31:57.0

stat fstat  fstatat lstat

stat系统调用系列包括了fstat、stat和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);

函数说明:    通过文件名pathname获取文件信息,并保存在buf所指的结构体stat中 
返回值:     执行成功则返回0,失败返回-1,错误代码存于errno 
错误代码: 
ENOENT         参数file_name指定的文件不存在 
ENOTDIR        路径中的目录存在但却非真正的目录 
ELOOP          欲打开的文件有过多符号连接问题,上限为16符号连接 
EFAULT         参数buf为无效指针,指向无法存在的内存空间 
EACCESS        存取文件时被拒绝 
ENOMEM         核心内存不足 
ENAMETOOLONG   参数file_name的路径名称太长 

例如:得到文件的大小

#include<sys/types.h>
#include<sys/stat.h>
int main()
{struct stat st;struct stat* st1;st1 = &st;int ret = stat("aaa.txt",&st);if(ret == -1){perror("stat error");exit(1);}printf("file size = %d\n",(int)st.st_size);return 0;
}

 

struct stat 结构体

buf参数的类型是struct stat的指针,struct stat 结构体在stat, fstatat ,fstat和lstat中都要用到,里面的成员也很多。

在Linux中stat定义为:

struct stat { dev_t         st_dev;       //文件的设备编号 ino_t         st_ino;       //节点 mode_t        st_mode;      //文件的类型和存取的权限 nlink_t       st_nlink;     //连到该文件的硬连接数目,刚建立的文件值为1 uid_t         st_uid;       //用户ID gid_t         st_gid;       //组ID dev_t         st_rdev;      //(设备类型)若此文件为设备文件,则为其设备编号 off_t         st_size;      //文件字节数(文件大小) unsigned long st_blksize;   //块大小(文件系统的I/O 缓冲区大小) unsigned long st_blocks;    //块数 time_t        st_atime;     //最后一次访问时间 time_t        st_mtime;     //最后一次修改时间 time_t        st_ctime;     //最后一次改变时间(指属性) 
}; 

其中st_mode域是需要一些宏予以配合才能使用的。其实,通俗说,这些宏就是一些特定位置为1的二进制数的外号,我们使用它们和st_mode进行”&”操作,从而就可以得到某些特定的信息。

linux 查看文件属性stat fstat fstatat lstat

 

st_mode 文件权限和文件类型信息 
使用不同的宏和st_mode做按位与操作就得到相应的权限值,掩码与st_mode就得到是否有读写执行三个权限

-st_mode --16位整数0-2bit -- 其他人权限-S_IROTH 00004 读权限-S_IWOTH 00002 写权限 -S_IXOTH 00001 执行权限-S_IRWXO 00007 掩码,过滤st_mode中除其他人权限以外的信息3-5bit -- 所属组权限-S_IRGRP 00040 读权限-S_IWGRP 00020写权限 -S_IXGRP 00010 执行权限-S_IRWXG 00070 掩码,过滤st_mode中除所属组权限以外的信息6-8bit -- 文件所有者权限-S_IRUSR 00400 读权限-S_IWUSR 00200写权限 -S_IXUSR 00100执行权限-S_IRWXU 00700掩码,过滤st_mode中除所有者权限权限以外的信息12-15bit --文件类型-S_IFSOCK  0140000 套接字-S_IFLNK     0120000 符号链接(软连接)-S_IFREG   0100000 普通文件-S_IFBLK     0060000 块设备-S_IFDIR     0040000 块目录-S_IFCHR    0020000 字符设备-S_IFIFO      0010000 管道-S_IFMT     掩码,过滤st_mode中除文件类型以外的信息

 

int main()
{struct stat st;struct stat* st1;st1 = &st;int ret = stat("aaa.txt",&st);if(ret == -1){perror("stat error");exit(1);}printf("file size = %d\n",(int)st.st_size);if((st.st_mode & S_IFMT) == S_IFREG){printf("这是一个普通文件\n");}return 0;
}
if(st.st_mode & S_IRUSR)
{printf("    r");
}
if(st.st_mode & S_IWUSR)
{printf("    w");
}
if(st.st_mode & S_IXUSR)
{print("     x");
}

 

再来看stat、fstat、fstatat和lstat的区别:

在很多linux函数里面都会有至少三个功能相近的函数原始的函数名前面加上l或者f,l就是link处理链接文件,f对于fd处理文件描述符。所以这里:

stat函数返回的pathname文件有关的信息结构,如果pathname是链接文件,stat读取的是链接文件指向的文件的属性,这种方式叫做追踪或者穿透。

lstat函数如果参数pathname是个链接文件,则读取的是链接文件本身的属性,其他情况下和stat相同。当以降序遍历目录层次结构时,需要用到lstat。

fstat函数获取的是在描述符fd打开文件的有关信息

fstatat函数为一个相对于当前打开目录(由fd参数指向)的路径名返回文件统计信息。flag参数控制着是否跟随着一个符号链接,设置为AT_SYMLINK_NOFOLLOW标志,fstatat不会跟随符号链接,返回链接文件本身的信息。默认下返回的是符号链接所指向的文件信息。如果参数fd设置为AT_FDCWD,并且pathname参数是一个相对路径名,fstatat会判断相对于当前目录的pathname参数,如果pathname是一个绝对路径,fd参数就会被忽略。

 

 

Linux stat命令用于显示inode内容

stat以文字的格式来显示inode的内容。

语法

stat [文件或目录]

实例

查看 testfile 文件的inode内容内容,可以用以下命令:

# stat testfile

执行以上命令输出结果:

# stat testfile                #输入命令File: `testfile'Size: 102             Blocks: 8          IO Block: 4096   regular file
Device: 807h/2055d      Inode: 1265161     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2014-08-13 14:07:20.000000000 +0800
Modify: 2014-08-13 14:07:07.000000000 +0800
Change: 2014-08-13 14:07:07.000000000 +0800