文件属性相关(一)
获取文件信息:
#include<stat.h>
int stat(const char *pathname,struct stat *statbuf);
int lstat(const char *pathname,struct stat *statbuf);//用于符号链接,指的是符号本身
int fstat(int fd,struct stat *statbuf);
成功返回0,失败-1
struct stat{
dev_t st_dev;//包含设备的主,辅ID
ino_t st_ino;//I-node number of file
mode_t st_mode;//file type and permissions,跟S_IFMT相与&,可析取文件类型例如S_IFREG等,下图是文件类型的常量
nlink_t st_nlink;//number of links to file
uid_t st_uid;//user id of file owner
gid_t st_gid;
dev_t st_rdev;
off_t st_size;//total file size
blksize_t st_blksize;//block size for i/o
blkcnt_t st_blocks;//number of 512b blocks allocated
time_t st_atime;//access
time_t st_mtime;//modification
time_t st_ctime;//status change
};
用法举例
if((stutbuf.st_mod&S_IFMT)==S_IFREG)
printf(“普通文件”);
或者
if(S_ISREG(statubuf.st_mode))
printf(“普通文件”);
[root@bogon ~]# cat test.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<time.h>
int main()
{
struct stat st;
if((stat("/root/a.txt",&st))!=0)
{
perror("stat");
exit(1);
}
if(S_ISREG(st.st_mode&S_IFMT))
printf("this is nomal file\n");
printf("last status change time :%s",ctime(&(st.st_ctime)));//因为st_ctime是time_t,是秒数而已,所以用ctime转换为日期字符串
return 0;
}
[root@bogon ~]# gcc test.c
[root@bogon ~]# ./a.out
this is nomal file
last status change time :Mon May 29 00:04:01 2017
[root@bogon ~]#
改变时间戳
#include<utime.h>
int utime(const char *pathname,const struct utimebuf *buf)//如果buf为NULL,那么文件上次访问和修改时间同时设置为当前时间,成功返回0,失败-1
struct utimebuf{
time_t actime;//access time
time_t modtime;//modification time
}
#include<sys/time.h>
int utimes(const char *pathname,const struct timeval tv[2])//精确到微秒,文件访问时间在tv[0]中指定,修改时间在tv[1]中指定,成功返回0,失败-1
还有
int futimes(int fd,const struct timeval tv[2])//顾名思义,把路径换成fd文件描述符罢了
int lutimes(const char *pathname,const struct timeval tv[2]);//针对符号链接本身
#include<sys/stat.h>
int utimensat(int dirfd,const char *pathname,const struct timespec times[2],int flags)//将times指定为NULL,那么时间戳会更新为当前时间,times[0]放置访问时间times[1]修改时间,成功返回0,失败-1,可以将dirfd指定为AT_FDCWD,或者指定为代指目录的文件描述符,flags参数可以为0或者AT_SYMLINK_NOFOLLOW
struct timespec{
time_t tv_sec;//秒数
long tv_nsec;//纳秒数,如果想设置当前时间,赋值UTIME_NOW,如果想保持不变,UTIME_OMIT,如果设置了这两个特殊值,tv_sec的值会自动忽略
};
int futimens(int fd,const struct timespec times[2])//,times参数与utimensat()相同,成功返回0,失败-1
修改文件属主
#include<unistd.h>
int chown(const char *pathname,uid_t owner,gid_t group)
int lchown(const char *pathname,uid_t owner,gid_t group)//针对符号链接
int fchown(int fd,uid_t owner,gid_t group)//成功0,失败-1
检查文件访问权限
#include<unistd.h>
int access(const char *pathname,int mode)
mode的值可以为
F_OK 有这个文件吗
R_OK,W_OK,X_OK 对该文件可读可写可执行吗
不建议使用该函数,该函数有安全漏洞
#include<sys/stat.h>
mode_t umask(mode_t mask)//将umask修改为mask
int chmod(const char *pathname,mode_t mode)
int fchmod(int fd,mode_t mode)
下面举个例子
[root@bogon code]# cat a.c
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<error.h>
#include<unistd.h>
int main()
{
umask(0444);
int fd=open("linux",O_CREAT,S_IWUSR|S_IRUSR);//设置文件可读可写,因为umask为0444,所以可读就没有了
if(fd==-1)
{
perror("open");
exit(1);
}
system("ls -l");
if((fchmod(fd,0777))==-1)
{
perror("fchmod");
exit(1);
}
system("ls -l");
return 0;
}
[root@bogon code]# gcc a.c
[root@bogon code]# ./a.out
total 16
-rw-r--r--. 1 root root 326 May 29 02:48 a.c
-rwxr-xr-x. 1 root root 8768 May 29 02:48 a.out
--w-------. 1 root root 0 May 29 02:48 linux
total 16
-rw-r--r--. 1 root root 326 May 29 02:48 a.c
-rwxr-xr-x. 1 root root 8768 May 29 02:48 a.out
-rwxrwxrwx. 1 root root 0 May 29 02:48 linux
[root@bogon code]#
下面来看一下文件节点
lsattr filename 查看文件节点标志
chattr +ai filename 设置文件节点标志
FS_APPEND_FL 仅当指定O_APPEND标志是方能打开并写入,迫使所有对文件的更新对追加到文件尾部,例如日志文件就是如此
FS_COMPR_FL 文件内容经压缩后存储与磁盘上,使用这个标志并不划算
FS_DIRSYNC_FL 仅对目录跟新
FS_IMMUTABLE_FL 将文件设置为不可更改,既不能更新文件数据也不能改变元数据
FS_JOURNAL_DATA_FL 对数据启用日志功能,只有ext3和ext4文件系统才支持该标志
FS_NOATIME_FL 访问文件是不更新文件的上次访问时间
FS_NODUMP_FL 在使用dump备份系统是跳过具有该标志的文件
FS_NOTAIL_FL 禁止尾部打包,只有Reiserfs文件系统才支持
FS_SECRM_FL 安全删除文件(不知道该特性实现没有现在)
FS_SYNC_FL 令对文件的更新保持同步
FS_TOPDIR_FL
FS_UNRM_FL 允许该文件在遭到删除后能得以恢复