#include<sys/types.h>
#include<sys/stat.h>
int stat(const char *restrict pathname, struct stat *restrict buf);
提供文件名字,获取文件对应属性。感觉一般是文件没有打开的时候这样操作。
int fstat(int filedes, struct stat *buf);
通过文件描述符获取文件对应的属性。文件打开后这样操作
int lstat(const char *restrict pathname, struct stat *restrict buf);
连接文件
三个函数的返回:若成功则为0,若出错则为-1
给定一个pathname,stat函数返回一个与此命名文件有关的信息结构,fstat函数获得已在描述符filedes上打开的文件的有关信息。lstat函数类似于stat,但是当命名的文件是一个符号连接时,lstat返回该符号连接的有关信息,而不是由该符号连接引用的文件的信息。
第二个参数是个指针,它指向一个我们应提供的结构。这些函数填写由buf指向的结构。该结构的实际定义可能随实现而有所不同,但其基本形式是:
函数都是获取文件(普通文件,目录,管道,socket,字符,块()的属性。
函数原型
#include <sys/stat.h>
int stat(const char *restrict pathname, struct stat *restrict buf);
提供文件名字,获取文件对应属性。
int fstat(int filedes, struct stat *buf);
通过文件描述符获取文件对应的属性。
int lstat(const char *restrict pathname, struct stat *restrict buf);
连接文件描述命,获取文件属性。
2 文件对应的属性
struct stat {
mode_t st_mode; //文件对应的模式,文件,目录等
ino_t st_ino; //inode节点号
dev_t st_dev; //设备号码
dev_t st_rdev; //特殊设备号码
nlink_t st_nlink; //文件的连接数
uid_t st_uid; //文件所有者
gid_t st_gid; //文件所有者对应的组
off_t st_size; //普通文件,对应的文件字节数
time_t st_atime; //文件最后被访问的时间
time_t st_mtime; //文件内容最后被修改的时间
time_t st_ctime; //文件状态改变时间
blksize_t st_blksize; //文件内容对应的块大小
blkcnt_t st_blocks; //伟建内容对应的块数量
};
可以通过上面提供的函数,返回一个结构体,保存着文件的信息。
stat函数讲解
表头文件: #include <sys/stat.h>
#include <unistd.h>
定义函数: int stat(const char *file_name, struct stat *buf);
函数说明: 通过文件名filename获取文件信息,并保存在buf所指的结构体stat中
返回值: 执行成功则返回0,失败返回-1,错误代码存于errno
错误代码:
ENOENT 参数file_name指定的文件不存在
ENOTDIR 路径中的目录存在但却非真正的目录
ELOOP 欲打开的文件有过多符号连接问题,上限为16符号连接
EFAULT 参数buf为无效指针,指向无法存在的内存空间
EACCESS 存取文件时被拒绝
ENOMEM 核心内存不足
ENAMETOOLONG 参数file_name的路径名称太长
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
int main() {
struct stat buf;
stat("/etc/hosts", &buf);
printf("/etc/hosts file size = %d\n", buf.st_size);
}
stat结构中最常用到的属性是st_mode(文件的类型及文件的访问权限)、st_nlink(硬链接数,表示有几个链接到该文件上)、st_uid、st_gid、st_size(以字节为单位的文件长度,只对普通文件、目录文件和符号连接有意义)、st_atime、st_mtime、st_ctime。
我们曾一再提到Unix系统中一切皆可视为文件,不过细而化之的话又可以分为多种类型,那么在程序中如何去对文件类型进行判别呢?这就需要用到下表中所示的一些宏:
宏
作用
S_ISREG()
测试是否为普通文件
S_ISDIR()
测试是否为目录文件
S_ISCHR()
测试是否为字符特殊文件
S_ISBLK()
测试是否为块特殊文件
S_ISFIFO()
测试是否为FIFO文件
S_ISLNK()
测试是否为链接文件
S_ISSOCK()
测试是否为socket文件
S_ISUID()
测试是否设置了“设置-用户-ID”位
S_ISGID()
测试是否设置了“设置-组-ID”位
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char * argv[])
{
int i;
struct stat buf;
char *ptr;
for(i=1; i< argc; i++)
{
printf("%s: ", argv[i]);
if(lstat(argv[i],&buf)<0)
{
printf("lstat error.");
continue;
}
if(S_ISREG(buf.st_mode)) ptr = "regular";
else if(S_ISDIR(buf.st_mode)) ptr = "directory";
else if(S_ISCHR(buf.st_mode)) ptr = "char special";
else if(S_ISBLK(buf.st_mode)) ptr = "block special";
else if(S_ISFIFO(buf.st_mode)) ptr = "fifo";
else ptr = "Others";
printf(" %s\n",ptr );
}
return 0;
}