struct stat结构体成员
struct stat{
dev_t st_dev; // 文件的设备编号
ino_t st_ino; // inode
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; // 文件字节数
blisize_t st_blksize; // 块大小
blkcnt_t st_blocks; // 块数
time_t st_atime; // 最后一次访问时间
time_t st_mtime; // 最后一次修改时间
time_t st_ctime; // 最后一次改变时间(指改变属性)
};
mode_t st_mode 位图
// 0-2位
S_IRWXO 00007 // 掩码,过滤st_mode中除其他人权限以外的信息
S_IROTH 00004 // 其他人读权限
S_IWOTH 00002 // 其他人写权限
S_IXOTH 00001 // 其他人执行权限
// 3-5位
S_IRWXG 00070 // 掩码,过滤st_mode中除所属组权限以外的信息
S_IRGRP 00040 // 所属组读权限
S_IWGRP 00020 // 所属组写权限
S_IXGRP 00010 // 所属组执行权限
// 6-8位
S_IRWXU 00070 // 掩码,过滤st_mode中除文件所有者权限以外的信息
S_IRUSR 00040 // 文件所有者读权限
S_IWUSR 00020 // 文件所有者写权限
S_IXUSR 00010 // 文件所有者执行权限
if(st_mode & S_IRUSR) // 为true表明可读
if(st_mode & S_IWUSR) // 为true表明可写
if(st_mode & S_IXUSR) // 为true表明可执行
// 12-15位,文件类型
S_IFMT 0170000 // 掩码,过滤st_mode中除文件类型以外的信息
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_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.)
if(st_mode & S_IFMT) == S_IFREG) // 为true,表明是普通文件
if(S_ISREG(st_mode)) // 为true,表明是普通文件
if(S_ISDIR(st.st_mode)) // 为tree,表明是目录文件
stat函数详解
int stat(const char *pathname, struct stat *buf);
// 穿透函数:操作软链接时,操作的是软链接指向的文件
// 类似的,cat mys,同样会穿透符号软件,cat的是符号链接mys指向的文件
// path:只读路径
// buf:传出参数
// 成功返回0,失败返回-1
fstat函数详解
int fstat(int fd, struct stat *buf);
lstat函数详解
int lstat(const char *pathname, struct stat *buf);
// 功能与stat一样,除了在操作软链接时不同,它操作的是软链接本身
stat结构体成员变量
access详解
int access(const char *pathname, int mode);
// 测试文件是否有某权限,是否存在
// R_OK,W_OK,X_OK,F_OK
lstat获取文件信息
// 用stat获取文件大小是比较正规的用法
// 用lseek方法获取文件大小是偏门
void test(const char* str)
{
struct stat buf;
int ret = lstat(str, &buf);
if(ret == -1)
{
perror("stat failed:");
exit(1);
}
// 获取文件大小
int size = (int)buf.st_size;
printf("size = %d\n", size);
// 获取文件类型
if(S_ISREG(buf.st_mode))
{
printf("是普通文件,");
}
else if(S_ISDIR(buf.st_mode))
{
printf("是目录文件,");
}
else if(S_ISCHR(buf.st_mode))
{
printf("是字符文件,");
}
else if(S_ISBLK(buf.st_mode))
{
printf("是块文件,");
}
else if(S_ISFIFO(buf.st_mode))
{
printf("是管道文件,");
}
else if(S_ISLNK(buf.st_mode))
{
printf("是符号链接文件,");
}
else if(S_ISSOCK(buf.st_mode))
{
printf("是套接字文件,");
}
// 获取文件权限
if(buf.st_mode & S_IRUSR)
{
printf("所有者权限是可读,");
}
if(buf.st_mode & S_IWUSR)
{
printf("所有者权限是可写,");
}
if(buf.st_mode & S_IXUSR)
{
printf("所有者权限是可执行");
}
printf("\n");
}
int main(int argc, char** argv)
{
if(argc < 2)
{
perror("usage:./mytarget fileName");
exit(1);
}
test(argv[1]);
return 0;
}
举例:获取文件类型
static int ftype(const char* fname)
{
struct stat st;
if(stat(fname, &st) < 0)
{
perror("stat()");
exit(1);
}
if(S_ISREG(st.st_mode))
{
return '-';
}
else if(S_ISDIR(st.st_mode))
{
return 'd';
}
else if(S_ISCHR(st.st_mode))
{
return 'c';
}
else if(S_ISBLK(st.st_mode))
{
return 'b';
}
else if(S_ISFIFO(st.st_mode))
{
return 'f';
}
else if(S_ISLNK(st.st_mode))
{
return 'l';
}
else if(S_ISSOCK(st.st_mode))
{
return 's';
}
else
{
return '?';
}
}
int main(int argc, char** argv)
{
if(argc < 2)
{
fprintf(stderr, "usage...\n");
exit(1);
}
printf("%c\n", ftype(argv[1]));
return 0;
}