Linux C++獲取文件夾大小


項目中要計算指定文件夾的大小。
百度查到這篇文章,https://my.oschina.net/Tsybius2014/blog/330628
方法可行,運行正確。

拿到我們的項目中,卻遇到一些問題:程序中一些讀文件的代碼,開始報異常,都不到文件。這些都是以前沒有遇到過的問題。
到底是什么情況呢?排查了好久,終於發現使用該文章提供的計算文件夾大小的函數(暫且叫做GetDirectorySize),其中有改變當前目錄的代碼:

chdir(dir);

我們的項目是多線程的,一個線程調用GetDirectorySize,調用的過程中改變了當前目錄,而此時另一個線程使用相對路徑去讀文件,原來能讀到的,現在就讀不到了。特別提示chdir改變的是,當前進程(當然包括其下所有線程)的工作目錄!!!(具體可以查看線程共享進程的那些資源?

為了去掉GetDirectorySize的副作用,我重新實現了該函數:

 1 #include <stdio.h>
 2 #include <sys/stat.h>
 3 #include <sys/types.h>
 4 #include <unistd.h>
 5 #include <stdlib.h>
 6 #include <dirent.h>
 7 #include <string.h>
 8 
 9 //計算某目錄所占空間大小(包含本身的4096Byte)
10 long long int GetDirectorySize(char *dir)
11 {
12     DIR *dp;
13     struct dirent *entry;
14     struct stat statbuf;
15     long long int totalSize=0;
16 
17     if ((dp = opendir(dir)) == NULL)
18     {
19         fprintf(stderr, "Cannot open dir: %s\n", dir);
20         return -1; //可能是個文件,或者目錄不存在
21     }
22     
23     //先加上自身目錄的大小
24     lstat(dir, &statbuf);
25     totalSize+=statbuf.st_size;
26 
27     while ((entry = readdir(dp)) != NULL)
28     {
29         char subdir[256];
30         sprintf(subdir, "%s/%s", dir, entry->d_name);
31         lstat(subdir, &statbuf);
32         
33         if (S_ISDIR(statbuf.st_mode))
34         {
35             if (strcmp(".", entry->d_name) == 0 ||
36                 strcmp("..", entry->d_name) == 0)
37             {
38                 continue;
39             }
40 
41             long long int subDirSize = GetDirectorySize(subdir);
42             totalSize+=subDirSize;
43         }
44         else
45         {
46             totalSize+=statbuf.st_size;
47         }
48     }
49 
50     closedir(dp);    
51     return totalSize;
52 }
53 
54 int main(int argc, char* argv[])
55 {
56     char* dir = argv[1];
57     long long int  totalSize = GetDirectorySize(dir);    
58     printf("totalSize: %lld\n", totalSize);
59 
60     return 0;
61 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM