my_ls总结

4 篇文章 0 订阅

刚开始写my_ls很没有头绪,因为对一些函数都很陌生,看过就又忘了,所以刚开始,就是照着Linux_c文件操作后面的例子抄的,然后通过函数之间的调用,慢慢的读代码,然后最后有了思路之后,就自己重新写了一个.
首先ls中主要就是应用了Linux文件操作的相关知识.

获取目录信息的函数
(1).opendir函数 ----------->用来打开参数name指定的目录
函数所需头文件:

#include<sys/types.h>
#include<dirent.h>

函数原型:

DIR *opendir(const char *name);

*返回DIR 形态的目录流 ------>类似于FILE文件描述符
失败返回NULL
(2).readdir函数 ------------>用来从参数dir所指向的目录中读取出目录项的信息
函数所需头文件:

#include<sys/types.h>
#include<dirent.h>

函数原型:

struct dirent *readdir(DIR *dir);

返回值: 一个struct dirent结构的指针

struct dirent
             {
                  long d_ino; /* inode number 索引节点号 */
                  off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
                  unsigned short d_reclen; /* length of this d_name 文件名长 */
                  char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
             }

第一次调用返回该目录下第一个文件信息,直到NULL

(3).closedir函数 -------------->用来关闭参数dir指向的目录
函数所需头文件:

#include<sys/types.h>
#include<dirent.h>

函数原型:

int closedir(DIR* dir);

返回值: 成功 0 错误 -1
对文件的操作主要函数:
函数所在头文件:

#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>

函数功能:用来获取linux操作系统下文件的属性。
函数原型:

int stat(const char *pathname,struct stat *buf);

struct stat {
dev_t st_dev; 文件的设备编号
ino_t st_ino; 节点
mode_t st_mode; 文件的类型和权限
nlink_t st_nlink; 连到该文件的硬链接数目,刚建立的文件值为1
uid_t st_uid; 用户ID
gid_t st_gid; 组ID
dev_t st_rdev; 设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; 文件字节数(文件大小)
blksize_t st_blksize; 块大小(文件I/O缓冲区的大小)
blkcnt_t st_blocks; 块数
time_t st_atime; 最后一次访问时间
time_t st_mtime; 最后一次修改时间
time_t st_ctime; 最后一次改变时间(指属性) };

但是在写ls的时候,用的函数是lstat,lstat函数对于链接文件是可以追述到源文件的
注意stat与lstat的区别:
stat碰到链接,会追述到源文件,穿透!!lstat并不会穿透。

其实对于-a,-l的实现并不是太难,主要是-R,刚开始想的是,把根目录下的所有目录名都存储起来,然后根据-l,-a那样把每个目录进行处理,这我居然都直接开始上手了,简直是个憨憨,后来一想,连个路径名都不全,怎么可能读到目录中的目录呢?
........
最后就重新换了一种思路,用的递归的写法,目录名不存储了,每次遇到一个就直接进行处理,这块的bug真的是把人搞崩溃了,gdb调试一下午,不是malloc有错,就是free出现了问题,现在终于体会到c语言老师当时说的,有的人malloc和free在实际些东西的时候就会不知道何时进行对应的处理.心累 但是还是有趣的

对于目录的操作和读取里面的内容,一定不能憨憨的用相对路径.

对于-l的写法,我们就要用到 struct stat结构体,从而得到文件的权限与属性,还有时间的操作,我是在网上学的这种处理方法

struct tm {
int tm_sec; /* Seconds (0-60) /
int tm_min; /
Minutes (0-59) /
int tm_hour; /
Hours (0-23) /
int tm_mday; /
Day of the month (1-31) /
int tm_mon; /
Month (0-11) /
int tm_year; /
Year - 1900 /
int tm_wday; /
Day of the week (0-6, Sunday = 0) /
int tm_yday; /
Day in the year (0-365, 1 Jan = 0) /
int tm_isdst; /
Daylight saving time */ };

//时间处理
struct tm *filetm = localtime(&file.st_mtim .tv_sec);
char timebuf[20];
memset(timebuf,'\0',sizeof(timebuf));
sprintf(timebuf,"%2d月  %2d %02d:%02d",filetm->tm_mon+1 ,filetm->tm_mday,filetm->tm_hour,filetm->tm_min);

对于信号的屏蔽,就要了解未决信号集,阻塞信号集,已经相关的操作函数,在这里先提到这里了,后续会有专门对于信号的博客的.
总之,还是要在应用中学习,刚开始看的天花乱坠的Linux_c编程实战这本书,现在经过不断的练习,倒也不那么难搞了.

最后附上写的代码:https://github.com/hchc32/TeamC/blob/master/hc/pratice/Linux_c/My_Ls.c

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值