這一章非常亂,而且難以看懂,因為沒有UNIX系列系統(tǒng)的基本知識的話,有的東西很難明白,而書上對于這些知識的內(nèi)容只是一筆帶過.所以我感覺這章如果不打算用LINUX類似的系統(tǒng)的話,只要大概了解一下就好.看看代碼即可.不用深究.而我也不打算寫那么詳細(xì).如果想學(xué)LINUX系統(tǒng)可以去看看鳥哥的兩本.介紹的很詳細(xì).
UNIX系列系統(tǒng)的目錄就是一種文件,因此,ls(UNIX系列系統(tǒng)的一個命令行命令,顯示目錄的文件信息.)只需要讀此文件就可獲得所有的文件名,但是如果需要獲取文件的其他信息,比如長度等,就需要系統(tǒng)調(diào)用.在MS-DOS中獲取文件名也需要系統(tǒng)調(diào)用.
UNIX系列系統(tǒng)的文件系統(tǒng)結(jié)構(gòu),目錄就是文件,它包含了一個文件名列表和一些指示文件位置的信息."位置"是一個指向inode表的索引,而文件的inode是存放除文件名以及實際數(shù)據(jù)之外的所有信息.目錄項通常僅包含兩個條目,文件名和inode編號(就是inode表中的編號.每個文件都有一個編號,用以將一些散亂的用這些相同的編號組合在一起)
結(jié)構(gòu)Dirent包含inode編號和文件名.文件名的最大長度由NAME_MAX設(shè)定,NAME)MAX的值由系統(tǒng)決定.opendir返回一個指向稱為DIR的結(jié)構(gòu)的指針,該結(jié)構(gòu)與結(jié)構(gòu)FILE類似,它將被readdir和closedir使用.所有這些信息存放在頭文件dirent.h中.
那個inode節(jié)點的信息也可以百度一下.
先看一下代碼吧.
主函數(shù)
如果沒有參數(shù)只有程序名,那就處理當(dāng)前目錄.
調(diào)用fsize函數(shù)處理.那個"."就是當(dāng)前目錄的意思,如果我沒記錯".."兩個點就是上一級目錄的意思.
有參數(shù)的話就調(diào)用fsize處理依次處理這些參數(shù).(一次處理一個.處理一個后while判斷式判斷是否還有參數(shù),如果有那么繼續(xù)處理.)
fsize函數(shù)
聲明了stat類型的結(jié)構(gòu)stbuf.
系統(tǒng)調(diào)用stat將name,就是傳入?yún)?shù)的信息填充到結(jié)構(gòu)stbuf中.
出錯顯示錯誤信息.
并退出函數(shù).
如果沒出錯就判斷結(jié)構(gòu)體中的文件類型成員是不是目錄,是目錄就調(diào)用dirwalk函數(shù).
然后再輸出這個目錄的大小.
首先是看dirwalk函數(shù),因為readdir和opendir都跟具體的系統(tǒng)有關(guān).而這兩個函數(shù)在這里的功能只是傳回一個指針而已.所以沒什么大礙.
opendir返回一個DIR結(jié)構(gòu)的指針.(就是目錄.這個結(jié)構(gòu)里包含了目錄的文件描述符和一個direct類型的結(jié)構(gòu),direct類型的結(jié)構(gòu)包含了一個inode節(jié)點的編號,還有一個文件名.)
然后用readdir返回一個指向目錄中文件的結(jié)構(gòu)指針,這個指針包含了節(jié)點編號和文件名(因為read讀取的是目錄文件,而目錄文件中就包含了文件名.而這個書上這個版本的目錄結(jié)構(gòu)就這兩個成員.所以每次讀入也是這兩個成員.)
繼續(xù)向下看,看這個返回來的指針的名字也就是需要判斷的這個文件的名字是不是目錄本身或者是父目錄.是的話終止當(dāng)前循環(huán),執(zhí)行下一次循環(huán).
最后就是看目錄名字(dir)加上文件名字是否超出名字允許的最大字符.超出就報錯.
之后可以看一下opendir和readdir函數(shù)
opendir通過一系列的條件驗證是否是目錄.
以下任何一個出錯都將退出函數(shù)并返回錯誤狀態(tài).
首先用open函數(shù)打開這個文件并將文件描述符給fd,(open的第三個函數(shù)是創(chuàng)建文件時的權(quán)限.第二個參數(shù)中有一個可選參數(shù)是如果沒有找到該文件則創(chuàng)建該文件,而創(chuàng)建文件的權(quán)限就依據(jù)第三個參數(shù).)
然后用fstat函數(shù)(與stat功能相同,只不過依據(jù)的不是文件名而是文件描述符.)將fd的信息填充到結(jié)構(gòu)體stbuf中.
之后判斷剛才結(jié)構(gòu)中的文件類型成員是不是目錄.
最后用malloc分配空間,并返回DIR類型的結(jié)構(gòu)指針給dp.
如果都沒出錯,將這個目錄文件的文件描述符復(fù)制給杠桿分配空間后的DIR結(jié)構(gòu)體重的相應(yīng)成員.
最后將該結(jié)構(gòu)體的指針返回.
接著去看readdir函數(shù)
每次通過read函數(shù)讀取目錄中的數(shù)據(jù),每次讀取dirbuf個長度的內(nèi)容,目錄中的每組數(shù)據(jù)都是dirbuf個長度的,所以每次都能讀到一組.然后是復(fù)制信息以便兼容.
這個最難想通的就是最后那個readdir函數(shù)通過read讀取目錄的內(nèi)容是怎么讀取的.
最后看了好幾遍書,知道了目錄文件都是這樣的結(jié)構(gòu),每次讀取都可以得到一組.
練習(xí)完全不用寫.就加了一個printf語句而已,