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或者描述符fd获取文件信息,并保存在buf所指的结构体stat中 ,struct 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进行”&”操作,从而就可以得到某些特定的信息。
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