stat 与 lstat
stat 命令的使用:
/**
* @author IYATT-yx
* @brief 获取文件部分属性
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char **argv)
{
if (argc != 2)
{
printf("请指定一个参数为要查询大小的文件!\n");
return -1;
}
struct stat st;
int ret = stat(argv[1], &st);
if (ret == -1)
{
perror("stat");
return -1;
}
printf("%s的大小为%ld\n", argv[1], st.st_size);
// 文件类型, 1法
if (S_ISREG(st.st_mode))
{
printf("1@这是一个普通文件\n");
}
else if (S_ISDIR(st.st_mode))
{
printf("1@这是一个目录文件\n");
}
else if (S_ISLNK(st.st_mode))
{
printf("1@这是一个符号链接文件\n");
}
else if (S_ISSOCK(st.st_mode))
{
printf("1@这是一个套接字文件\n");
}
else if (S_ISBLK(st.st_mode))
{
printf("1@这是一个块设备文件\n");
}
else if (S_ISCHR(st.st_mode))
{
printf("1@这是一个字符设备文件\n");
}
else if (S_ISFIFO(st.st_mode))
{
printf("1@这是一个管道文件\n");
}
// 文件类型, 2法
int type = st.st_mode & S_IFMT;
switch (type)
{
case S_IFREG:
printf("2@这是一个普通文件\n");
break;
case S_IFDIR:
printf("2@这是一个目录文件\n");
break;
case S_IFLNK:
printf("2@这是一个符号链接文件\n");
break;
case S_IFSOCK:
printf("2@这是一个套接字文件\n");
break;
case S_IFBLK:
printf("2@这是一个块设备文件\n");
break;
case S_IFCHR:
printf("这是一个字符设备文件\n");
break;
case S_IFIFO:
printf("这是一个管道文件\n");
break;
default:
break;
}
}
上面示例用的 stat
函数,类似的还有lstat
和fstat
. 使用stat与lstat的主要区别在软链接文件,当查询的是软链接文件时,stat会穿透查询到软链接指向的文件,而lstat可以查询软链接文件本身的属性.而fstat主要是参数区别, stat和lstat都是通过文件名查询,而fstat是通过open打开文件的返回值文件描述符进行查询.具体信息可以使用man
命令查询. 另外应该也容易注意到, stat系列函数可以查询的文件属性和 ls -l
显示的内容几乎差不多.
stat结构体
struct stat
{
// 文件的设备编号
dev_t st_dev;
// 节点
ino_t st_ino;
// 文件的类型和存取的权限
mode_t st_mode;
// 链到该文件的硬链接数目
nlink_t st_nlink;
// 用户ID
uid_t st_uid;
// 组ID
gid_t st_gid;
// (设备类型)若此文件为设备文件,则为其设备编号
dev_t st_rdev;
// 文件字节数
off_t st_size;
// 块大小 (文件系统的I/O缓冲区大小)
blksize_t st_blksize;
// 块数
blkcnt_t st_blocks;
// 最后一次访问时间
time_t st_atime;
// 最后一次内容修改时间
time_t st_mtime;
// 最后一次属性修改时间
time_t st_ctime;
};
st_mode (16位整数)
- 0~2位 o 其他用户
S_IROTH | 00004 | 读 |
S_IWOTH | 00002 | 写 |
S_IXOTH | 00001 | 执行 |
S_IRWXO | 00007 | 掩码,过滤非o的权限 |
* 3~5位 g 所属用户组
S_IRGRP | 00040 | 读 |
S_IWGRP | 00020 | 写 |
S_IXGRP | 00010 | 执行 |
S_IRWXG | 00070 | 掩码,过滤非g的权限 |
* 6~8位 u 文件所有者
S_IRUSR | 00400 | 读 |
S_IWUSR | 00200 | 写 |
S_IXUSR | 00100 | 执行 |
S_IRWXU | 00700 | 掩码,过滤非u权限 |
* 12~15位 文件类型
S_IFSOCK | 0140000 | 套接字 |
S_IFLNK | 0120000 | 符号链接 (软链接) |
S_IFREG | 0100000 | 普通文件 |
S_IFBLK | 0060000 | 块设备 |
S_IFDIR | 0040000 | 目录 |
S_IFCHR | 0020000 | 字符设备 |
S_IFIFO | 0010000 | 管道 |
S_IFMT | 0170000 | 淹码,过滤非文件类型的信息 |
/**
* @author IYATT-yx
* @brief 检测文件属性: 存在,读,写,操作
*/
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv)
{
if (argc != 2)
{
printf("请指定一个参数为要查询的文件!\n");
return -1;
}
if (access(argv[1], F_OK) == -1)
{
perror("access");
return -1;
}
else
{
if (access(argv[1], R_OK) == 0)
{
printf("R");
}
if (access(argv[1], W_OK) == 0)
{
printf("W");
}
if (access(argv[1], X_OK) == 0)
{
printf("X");
}
printf("\n");
}
}
修改文件权限: chmod
函数
修改文件所有者或所属组: chown
函数
修改文件大小: truncate
函数
改变已经打开的文件的属性: fcntl
函数