版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
一、access函数
1、access函数
int access(const char *pathname, int mode);
//功能:测试文件的访问权限以及是否存在,通常用来判断文件是否存在
//参数1:文件路径
//参数2有以下四种类型,函数对应的功能不同
//F_OK 文件是否存在
//R_OK 文件是否具有读权限
//W_OK 文件是否具有写权限
//X_OK 文件是否具有执行权限
//返回值:如果具有某种权限则返回0,否则返回-1
使用例子:
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
int main()
{
//判断当前目录下是否存在test.txt文件
if(0 == access("./test.txt",F_OK))
{
puts("存在");
}
else
{
puts("不存在");
}
}
除此之外我们还可以使用open返回值来判断文件是否存在,如果文件描述符为-1则说明文件不存在、
二、link/unlink函数
1、link函数
int link(const char *oldpath, const char *newpath);
//创建一个硬链接文件
//参数1:源文件路径
//参数2:硬链接文件的路径
//返回值:创建成功返回0,失败返回-1
使用例子:
#include <stdio.h>
#include <unistd.h>
int main()
{
//先判断文件是否存在
if(0 > access("./test.txt",F_OK))
{
printf("file does not exist\n");
return -1;
}
//在当前目录下在创建一个硬链接文件
if(0 > link("./test.txt","./demo.txt"))
{
perror("link");
return -1;
}
}
2、unlink函数
int unlink(const char *pathname);
//功能:删除硬链接文件,如果硬链接文件的数目为1则删除该文件
//参数1:删除文件的文件路径
//返回值:成功返回0,失败返回-1
使用例子:
#include <stdio.h>
#include <unistd.h>
int main()
{
//检查文件是否存在
if(0 > access("./test.txt",F_OK))
{
printf("file does not exist\n");
return -1;
}
//删除文件
if(0 > unlink("./test.txt"))
{
perror("unlink");
return -1;
}
}
普通文件相当于硬链接数为1的文件。
三、rename函数
int rename(const char *oldpath, const char *newpath);
//功能:重命名文件名
//参数1:旧路径名
//参数2:新路径名
//返回值:成功返回0,失败返回-1
使用例子
#include <stdio.h>
#include <unistd.h>
int main()
{
if(0 < access("./test.txt",F_OK))
{
printf("file does not exist\n");
return -1;
}
if(0 < rename("./test.txt","./haha.txt"))
{
perror("rename");
return -1;
}
}
四、stat/fstat/lstat
int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
//这三个函数的功能相同,都是获取文件的状态,只不过第一个参数不同
//参数1:stat和lstat的第一个参数相同都是为文件的路径,fstat的第一个参数为文件描述符
//参数2::是一个表示文件状态的结构体
一下为struct stat的成员变量:
struct stat {
dev_t st_dev; // 设备ID
ino_t st_ino; // 节点号
mode_t st_mode; // 文件类型和权限
nlink_t st_nlink; // 硬链拉数
uid_t st_uid; // 用户ID
gid_t st_gid; // 组ID
dev_t st_rdev; // 特殊设备ID
off_t st_size; // 文件的总字节数
blksize_t st_blksize; // IO块数
blkcnt_t st_blocks; // 占用块(512字节)数
time_t st_atime; // 最后访问时间
time_t st_mtime; // 最后修改时间
time_t st_ctime; // 最后文件属性修改时间
}
举例:打印一个文件的基本信息(权限+最后访问时间)
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
char* list_str(mode_t mode,char* mode_str)
{
if(S_ISREG(mode)) mode_str[0] = '-'; //测试是否是标准文件
else if(S_ISDIR(mode)) mode_str[0] = 'd'; //测试是否是目录
else if(S_ISBLK(mode)) mode_str[0] = 'b'; //测试是否是块设备文件
else if(S_ISCHR(mode)) mode_str[0] = 'c'; //测试是否是字符设备文件
else if(S_ISFIFO(mode)) mode_str[0] = 'q'; //测试是否是管道文件
else if(S_ISLNK(mode)) mode_str[0] = 'l'; //测试是否是软链接文件
else if(S_ISSOCK(mode)) mode_str[0] = 's'; //测试是否是socket文件
else mode_str[0] = '?'; //
mode_str[1] = '\0';
strcat(mode_str,S_IRUSR & mode ? "r" : "-"); //测试属主是否有读权限
strcat(mode_str,S_IWUSR & mode ? "w" : "-"); //测试属主是否有写权限
strcat(mode_str,S_IXUSR & mode ? "x" : "-"); //测试属主是否有执行权限
strcat(mode_str,S_IRGRP & mode ? "r" : "-"); //测试属组是否有读权限
strcat(mode_str,S_IWGRP & mode ? "w" : "-"); //测试属组是否有写权限
strcat(mode_str,S_IXGRP & mode ? "x" : "-"); //测试属组是否有执行权限
strcat(mode_str,S_IROTH & mode ? "r" : "-"); //测试其它用户是否有读权限
strcat(mode_str,S_IWOTH & mode ? "w" : "-"); //测试其它用户是否有写权限
strcat(mode_str,S_IXOTH & mode ? "x" : "-"); //测试其它用户是否有执行权限
return mode_str;
}
char* time_str(time_t time,char* t_str)
{
struct tm* t = localtime(&time);
sprintf(t_str,"%4d-%02d-%02d",t->tm_year+1900,t->tm_mon+1,t->tm_mday);
return t_str;
}
int main()
{
if(0 < access("./haha.txt",F_OK))
{
printf("file does not exist\n");
return -1;
}
struct stat s = {};
stat("./haha.txt",&s);
char t_str[100] = {};
char mode_str[100] = {};
printf("%s %s",list_str(s.st_mode,mode_str),time_str(s.st_atime,t_str));
}
运行效果: