首頁技術(shù)文章正文

Linux 文件目錄樹的遍歷

更新時(shí)間:2017-11-16 來源:黑馬程序員 瀏覽量:

1. linux提供opendir、readdir(readdir_r)、closedir和scandir等接口實(shí)現(xiàn)對(duì)目錄的讀取。

2. readdir返回指向下一個(gè)目錄項(xiàng)的指針,如果要自己傳入緩沖區(qū)存儲(chǔ)目錄項(xiàng),應(yīng)使用readdir_r代替。readdir的結(jié)果中包含當(dāng)前目錄和上一級(jí)目錄的目錄項(xiàng)信息。

3. 在遍歷過程中,進(jìn)程的工作目錄不會(huì)改變,在遞歸遍歷的時(shí)候,需要改變工作目錄(chdir)以識(shí)別相對(duì)路徑,或者每次都限定全局路徑。

4. 深度優(yōu)先遍歷目錄樹采用遞歸實(shí)現(xiàn)易編碼(參見如下代碼),廣度優(yōu)先遍歷則需借助隊(duì)列實(shí)現(xiàn)。當(dāng)目錄下的文件數(shù)量較少時(shí),采用廣度優(yōu)先遍歷效率會(huì)更高,因目錄下的目錄項(xiàng)基本都是連續(xù)存放,減少了很多磁盤尋道;而采用深度優(yōu)先遍歷,結(jié)果的聚合性更高。

1. int dir_traverse(const char *dir_name)

2. {

3. DIR *dirp = opendir(dir_name);

4. if(!dirp) {

5. perror("opendir");

6. return -1;

7. }

8.

9. struct stat st;

10. struct dirent *dir;

11. char fullpath[FILENM_MAX];

12. while((dir = readdir(dirp)) != NULL) {

13. if(!strcmp(dir->d_name, ".") || // 考慮當(dāng)前目錄和上級(jí)目錄,否則會(huì)死循環(huán)

14. !strcmp(dir->d_name, "..")) {

15. continue;

16. }

17.

18. sprintf(fullpath, "%s/%s", dir_name, dir->d_name); //獲取全局路徑

19. printf("%s\n", fullpath); // 打印路徑

20. if(lstat(fullpath, &st) < 0) {

21. perror("lstat");

22. continue;

23. }

24. if(S_ISDIR(st.st_mode)) {

25. dir_traverse(fullpath); // 遞歸遍歷子目錄

26. }

27.

28. }

29.

30. closedir(dirp);

31.

32. return 0;

33. }

訪問目錄下某個(gè)文件時(shí),需要逐個(gè)讀取目錄數(shù)據(jù)中的目錄項(xiàng)并與目標(biāo)進(jìn)行匹配獲得文件的inode號(hào),假設(shè)文件的平均長(zhǎng)度為10byte,加上inode、type及reclen等信息,每個(gè)目錄項(xiàng)的平均長(zhǎng)度為16byte,假設(shè)采用4K的數(shù)據(jù)塊,則一個(gè)塊可以存放256個(gè)目錄項(xiàng),按照ext2文件數(shù)據(jù)索引的方式,當(dāng)目錄下文件數(shù)n少于256*12時(shí),則在目錄下查找文件最多需要訪問n/256(向上取整)個(gè)數(shù)據(jù)塊,當(dāng)目錄下文件數(shù)更多的時(shí)候,需要訪問的塊數(shù)會(huì)更快的增加(后面得到存儲(chǔ)數(shù)據(jù)的物理塊號(hào)需要多級(jí)索引),這也是在目錄下不應(yīng)放太多文件的原因,如果將擁有很多文件的目錄均分成多個(gè)子目錄,多一級(jí)目錄會(huì)多一次(或多次,具體依賴于子目錄下文件數(shù)量)磁盤塊訪問,但在子目錄中查找文件的磁盤訪問開銷會(huì)小很多。

友情提示:獲得更多學(xué)科學(xué)習(xí)視頻+資料+源碼,請(qǐng)加QQ:3276250747。


本文版權(quán)歸黑馬程序員C/C++學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!


作者:黑馬程序員C/C++培訓(xùn)學(xué)院


首發(fā):http://c.itheima.com/


分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!