这一章非常乱,而且难以看懂,因为没有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语句而已,
网友评论