linux下獲取硬碟使用情況[總結]
1、前言
在嵌入式裝置中,硬碟空間非常有限,在涉及到經常寫日誌的程序時候,需要考慮日誌的大小和刪除,不然很快就硬碟寫滿,導致日誌程式崩潰。為了捕獲硬碟寫滿的異常場景,我們需要在寫日誌過程中判斷硬碟空間的使用情況,根據硬碟的使用情況,就可以判斷是否寫滿了。如果將要寫滿了,就給出警告。這樣就可以避免程式崩潰。首先看一下linux獲取硬碟和目錄大小的命令,最後總結一下statfs結構和函式。
2、df命令
Linux下可以用df命令獲取硬碟的使用情況,通過man可以獲取df命令的詳細情況。df命令經常用的引數為:
a:顯示全部的檔案系統和各分割區的磁碟使用情形
i:顯示i -nodes的使用量
k:大小用k來表示 (預設值)
t:顯示某一個檔案系統的所有分割區磁碟使用量
x:顯示不是某一個檔案系統的所有分割區磁碟使用量
T:顯示每個分割區所屬的檔案系統名稱
常用命令:df -hi
舉例截圖如下所示
:
3、du命令
du命令用來查詢檔案或目錄的磁碟使用空間,通過man獲取du命令的詳細介紹。常用的命令引數如下:
a:顯示全部目錄和其次目錄下的每個檔案所佔的磁碟空間
b:大小用bytes來表示 (預設值為k bytes)
c:最後再加上總計 (預設值)
s:只顯示各檔案大小的總合 (summarize)
x:只計算同屬同一個檔案系統的檔案
L:計算所有的檔案大小
常用命令:du -ah
舉例操作如下圖所示:
簡單總結一下:df與du的區別,du檢視目錄大小,df檢視磁碟使用情況。
關於df和du詳細介紹可以參考:
http://www.douban.com/group/topic/2833196
/http://blog.csdn.net/kmesg/article/details/6570800
4、statfs結構及函式
之前在看APUE時候,在第四章檔案和目錄中,講到了獲取檔案資訊的stat結構,通過stat結構可以獲檔案的大小,建立時間,修改時間,使用者id,組id等等。關於stat結構請參考:http://linux.about.com/library/cmd/blcmdl2_stat.htm。man上stat結構及操作函式如下圖所示:
今天主要總結學習一下獲取硬碟資訊的statfs結構,通過statfs結構的資訊計算出路徑所在的磁碟使用情況。
man上關於statfs介紹如下所示:
statfs結構的中文意思如下所示:
1 struct statfs 2 { 3 long f_type; /* 檔案系統型別*/ 4 long f_bsize; /* 經過優化的傳輸塊大小*/ 5 long f_blocks; /* 檔案系統資料塊總數*/ 6 long f_bfree; /* 可用塊數*/ 7 long f_bavail; /* 非超級使用者可獲取的塊數*/ 8 long f_files; /* 檔案結點總數*/ 9 long f_ffree; /* 可用檔案結點數*/ 10 fsid_t f_fsid; /* 檔案系統標識*/ 11 long f_namelen; /* 檔名的最大長度*/ 12 };
statfs結構中可用空間塊數有兩種f_bfree和 f_bavail,前者是硬碟所有剩餘空間,後者為非root使用者剩餘空間,ext3檔案系統給root使用者分有5%的獨享空間,所以這裡是不同的地方。這裡要強調的是每塊的大小一般是4K。因此,要實現與df結果一致的就得在獲得塊數上乘以4,這樣已用、可用、總塊數就可以實現。
測試程式如下所示:
1 #include <stdio.h> 2 #include <sys/statfs.h> 3 #include <sys/vfs.h> 4 #include <errno.h> 5 6 int main(int argc, char *argv[]) 7 { 8 struct statfs disk_info; 9 char *path = "/home/"; 10 int ret = 0; 11 if (argc == 2) 12 { 13 path = argv[1]; 14 } 15 if (ret == statfs(path, &disk_info) == -1) 16 { 17 fprintf(stderr, "Failed to get file disk infomation,\ 18 errno:%u, reason:%s\n", errno, strerror(errno)); 19 return -1; 20 } 21 long long total_size = disk_info.f_blocks * disk_info.f_bsize; 22 long long available_size = disk_info.f_bavail * disk_info.f_bsize; 23 long long free_size = disk_info.f_bfree * disk_info.f_bsize; 24 //輸出每個塊的長度,linux下記憶體塊為4KB 25 printf("block size: %ld bytes\n", disk_info.f_bsize); 26 //輸出塊個數 27 printf("total data blocks: %ld \n", disk_info.f_blocks); 28 //輸出path所在磁碟的大小 29 printf("total file disk size: %d MB\n",total_size >> 20); 30 //輸出非root使用者可以用的磁碟空間大小 31 printf("avaiable size: %d MB\n",available_size >> 20); 32 //輸出硬碟的所有剩餘空間 33 printf("free size: %d MB\n",free_size >> 20); 34 //輸出磁碟上檔案節點個數 35 printf("total file nodes: %ld\n", disk_info.f_files); 36 //輸出可用檔案節點個數 37 printf("free file nodes: %ld\n", disk_info.f_ffree); 38 //輸出檔名最大長度 39 printf("maxinum length of file name: %ld\n", disk_info.f_namelen); 40 return 0; 41 }