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