目录及文件属性

来源:互联网 发布:学电脑编程好不好 编辑:程序博客网 时间:2024/05/17 19:58
通过ls命令熟悉目录与文件的基础属性很有帮助,先通过如何获取ls的信息,再到理解ls所表示的信息的含义,深入浅出。现在自己的学习心态也不一样,复习之前知识之后,理解深入了很多。
ls的整体实现逻辑很简单,主要就是通过DIR, dirent, stat三个结构体,层层解析,获取到由简入深的文件及目录信息。但三个结构体的关系与含义却比较复杂,下面详解:
结构体DIR,是最开始的步骤,由目录路径获取操作目录的指针,通过DIR *opendir(const char *path)产生。此结构体成员不太重要,重要的是可操作它的函数。
有struct dirent *readdir(DIR *dp), void rewinddir(DIR *dp), int closedir(DIR *dp), long telldir(DIR *dp), void seekdir(DIR *dp, long loc)。
readdir函数可返回一个dirent结构体,
struct dirent{
     ino_t                     d_ino;
     odd_t                    d_off;
     unsigned short       d_reclen;
     char                      d_name[1]
}
相当于从DIR结构体所包含的目录中读出了其目录下的目录与文件信息,其内有name等简单记录。dirent结构体中name的存储形式,在linux中为d_name[MAX_SIZE+1],而在unix中为d_name[1],其只能存储一个字符,即字符串结束符'\0'。linux系统的name存储很好理解,一次性分配足够大的数组用作存储。而unix系统分配文件名空间时,会利用dirent中的另一个元素d_reclen。先用d_name[1]的地址位减去dirent的地址位,得到dirent中除了文件名空间之外所需要的空间,再以reclen的值减去之前的差,即可的所需malloc出的文件名空间大小,由此实现动态数组的功能。至于为何用array而不用char *,通过上述方法array几乎不占内存,而后者需要分配char即4个字节,可以节省内存。但是网上很多所说array不需要再赋值之类的话就不太理解,下次请教一下高人吧。
我们从dirent中得到文件夹内的信息,大致可以满足ls的功能,但是如果要实现ls -l的功能,则必须要使用结构体stat。
struct stat {  
 
        mode_t     st_mode;       //文件访问权限  
 
        ino_t      st_ino;       //索引节点号  
 
        dev_t      st_dev;        //文件使用的设备号  
 
        dev_t      st_rdev;       //设备文件的设备号  
 
        nlink_t    st_nlink;      //文件的硬连接数  
 
        uid_t      st_uid;        //所有者用户识别号  
 
        gid_t      st_gid;        //组识别号  
 
        off_t      st_size;       //以字节为单位的文件容量  
 
        time_t     st_atime;      //最后一次访问该文件的时间  
 
        time_t     st_mtime;      //最后一次修改该文件的时间  
 
        time_t     st_ctime;      //最后一次改变该文件状态的时间  
 
        blksize_t st_blksize;    //包含该文件的磁盘块的大小  
 
        blkcnt_t   st_blocks;     //该文件所占的磁盘块  
};  (其中备注为网友整理)
stat结构体详细记录了文件信息,而调用stat结构体的stat函数需要传入fname参数。函数int stat(char *fname, struct stat *bufp)将信息存储在stat结构体中。
具体的数据导向及格式化输出都没有什么难度,但是在运行./ls02 tmp的时候能够输出.及..的信息,而其内文件却总是被stat报错。后来发现,是文件路径的问题。假设a.txt、b.txt等存储在/root/tmp文件夹内,而当我们在/root文件夹内运行./ls02 tmp时,将a.txt传入stat时,程序一直认为是在找/root/a.txt、/root/b.txt,当然也就找不到了,实际上显示的.及..也并不是tmp文件夹内的,而是/root/下的,也就没有报错。
解决方法有两个:1、用chdir。2、在每个文件名前面都把路径补全。
下面贴上我的ls02(用了第一种方法)

参考:http://www.liweifan.com/2012/05/13/linux-system-function-files-operation/
          http://stackoverflow.com/questions/5125919/stat-error-no-such-file-or-directory
          http://www.lupaworld.com/home.php?mod=space&uid=56821&do=blog&id=121803





0 0
原创粉丝点击