Linux之管理檔案
學習前兩點要注意的是:
- 要留意一些低版本的函數和系統函數,能用高版本的就用高版本的。
- 能用 c 庫中的函數就用 c 庫中的函數,而不要用系統的函數和接口,c 的移植性更強,任何系統函數換了平台都可能無法使用了,但是絕大多數平台都可以支援 c 庫,包括 Android,QtE 等等平台。
一、 檔案中繼資料以及基礎知識
每一個檔案都有一個索引節點 inode,inode 是由檔案系統提供的唯一數值編址,這個數值稱為 inode 編号。索引節點是唯一的,同一個系統下,每一個索引節點對應一個檔案(目錄也可以當做檔案),inode 中存儲了與檔案相關的中繼資料,例如通路權限,通路時間,所有者,使用者組,大小以及檔案資料存儲位置。
如下圖所示,在虛拟機的 Ubuntu 系統下使用指令“ls -i”,可以看到檔案和目錄的 inode。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN2XjlGcjAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHLyEFRNp3Z65EeRpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLxcTM2EjNzYTMxEDNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
另外在啟動開發闆,在超級終端中也可以使用這個指令,如下圖所示。
如上圖所示,可以看到各種不同的索引節點。不知道大家發現沒有目錄 proc 和 sys 的索引節點是一樣的,這兩個其實都是指向同一個檔案,就像一個人有小名和學名一樣,指的都是同一個人。這種情況是屬于 linux 檔案中的硬連結,在後面會介紹到。
二、stat 函數組
從這個實驗開始,會更多的使用 man 來學習各種函數和 API 接口。
本節會介紹詳細一些,這個過程大家好掌握,後面的實驗就很直接的給出截圖和分析函數的使用了。如果覺得掌握的不夠,自己看幾頁 man 的文檔也花不了多長時間,畢竟它是如此重要的知識點。
1、使用 man 學習 stat 函數組
如下圖所示,使用指令“man 2 stat”檢視 stat 函數組的文檔。可以看到函數的頭檔案以及函數組。
如下圖所示,可以看到儲存檔案的結構體 struct stat,如下圖所示,可以看到非常詳細的結構成員注釋。
下翻一下,可以看到很多的宏定義解釋,這些具體用到的時候可以來查閱,如下圖所示,是結構成員 st_mode 的參數。
其實下面對于系統函數或者 API 的介紹,在 man 文檔中都有介紹,大家可以自己嘗試着看一下部分英文的内容。
int stat(const char *path, struct stat *buf);
//參數*path:檔案路徑。
//參數*buf:檔案資訊。
//傳回值:成功為 0,否則為-1。
int fstat(int fd, struct stat *buf);
//參數 fd:檔案描述符。
//參數*buf:檔案資訊
//傳回值:成功為 0,否則為-1。
int lstat(const char *path, struct stat *buf);
//參數*path:檔案路徑。
//參數*buf:傳回檔案的資訊,針對符号連結,lstat 傳回連結本身,而不是而非目标檔案;
//stat 傳回的是目标檔案。連結可以類比 window 下的快捷方式。
//傳回值:成功為 0,否則為-1。
2、stat 函數組例程
#include <stdio.h>
//通過man文檔可以檢視到stat函數組頭檔案
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
//open函數的參數頭檔案
#include <fcntl.h>
int main(int argc,char *argv[])
{
struct stat groupstat;
int fd,ret;
if(argc <2){
printf("\nPlease input file path\n");
return 1;
}
//stat函數測試
ret = stat(argv[1],&groupstat);
if(ret){
printf("Please make sure file path\n");
return 1;
}
printf("stat function test , %s of st_ino inode is %ld\n",argv[1],groupstat.st_ino);
//fstat函數測試
fd = open(argv[1],O_RDWR|O_NOCTTY|O_NDELAY);
if(fd<0)
{
printf("Please make sure file path\n");
return 1;
}
ret = fstat(fd,&groupstat);
if(ret){
printf("Please make sure file path\n");
return 1;
}
printf("fstat function test , %s of st_ino inode is %ld\n",argv[1],groupstat.st_ino);
//lstat函數測試
ret = lstat(argv[1],&groupstat);
if(ret){
printf("Please make sure file path\n");
return 1;
}
printf("lstat function test , %s of st_ino inode is %ld\n",argv[1],groupstat.st_ino);
return 0;
}
3、測試結果
三、chmod 權限函數
1、 使用 man 學習 chmod 函數
如下圖所示,使用指令“man 2 chmod”。有 chmod 和 fchmod 兩個函數。
接着介紹一下 chmod 和 fchmod 的用法。
int chmod(const char *path, mode_t mode);
//參數*path:檔案路徑。
//參數 mode:直接使用數字即可。和前面指令中 chmod 777 xxx 中的 777 這個參數含義類似,也可以使用文檔中的組合值。
//傳回值:成功傳回 0,錯誤傳回-1。
int fchmod(int fd, mode_t mode);
//參數 fd:檔案描述符。
//參數:直接使用數字即可。和前面指令中 chmod 777 xxx 中的 777 這個參數含義類似,也可以使用文檔中的組合值。
//傳回值:成功傳回 0,錯誤傳回-1。
2、chmod 函數例程
編寫簡單的 chmod.c 檔案測試 chmod 和 fchmod 函數。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
int fd,ret;
if(argc <3){
printf("\nPlease input file path\n");
return 1;
}
//chmod函數測試
ret = chmod(argv[1],0777);
if(ret<0){
printf("Please make sure file path\n");
return 1;
}
printf("chmod %s 0777 is success!\n",argv[1]);
//fchmod函數測試
fd = open(argv[2],O_RDWR|O_NOCTTY|O_NDELAY);
if(fd<0)
{
printf("Please make sure file path\n");
return 1;
}
ret = fchmod(fd,0555);
if(ret<0){
printf("Please make sure file path\n");
return 1;
}
printf("fchmod %s 0555 is success!\n",argv[1]);
return 0;
}
3、測試結果
如上圖所示,将./mnt/udisk 中的 stat 和 stat.c 檔案權限修改,然後使用指令“ls -l”檢視權限,可以看到修改成功。