Linux下文件操作(二)

一、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));
}

運行效果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章