一、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));
}
運行效果: