码迷,mamicode.com
首页 > 其他好文 > 详细

基础练习1——ls的实现与递归

时间:2019-11-02 21:57:53      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:das   size   lse   位移   type   接下来   number   hid   tor   

  学习贵在坚持,兜兜转转,发现还是从基础做起吧,打好基础,才会长期的坚持下去。。。

  第一个练习:shell命令 “ls"的实现与递归

  1、简介:ls 的作用是列举当前目录下所有的目录和文件。

  2、用到的结构体——struct dirent;

技术图片
1 struct dirent   
2 {   
3   long d_ino; /* inode number 索引节点号 */       
4     off_t d_off; /* offset to this dirent 在目录文件中的偏移 */       
5     unsigned short d_reclen; /* length of this d_name 文件名长 */       
6     unsigned char d_type; /* the type of d_name 文件类型 */       
7     char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */  
8 }
View Code

  struct dirent 结构体中成员d_type文件类型的分类:

技术图片
 1 enum
 2 { 
 3     DT_UNKNOWN = 0,  //类型未知。少数文件系统会出现此函数不支持的文件类型,另一些则总是返回这个值。译者注:总之这个值是为了应对不兼容的文件系统而设置的;
 4  # define DT_UNKNOWN DT_UNKNOWN 
 5      DT_FIFO = 1, // 一个命名管道,或FIFO
 6  # define DT_FIFO DT_FIFO 
 7      DT_CHR = 2, // 字符设备
 8  # define DT_CHR DT_CHR 
 9      DT_DIR = 4, // 目录
10  # define DT_DIR DT_DIR 
11      DT_BLK = 6, // 块设备
12  # define DT_BLK DT_BLK 
13      DT_REG = 8, // 常规文件
14  # define DT_REG DT_REG 
15      DT_LNK = 10, // 符号链接
16  # define DT_LNK DT_LNK 
17      DT_SOCK = 12, // 套接字
18  # define DT_SOCK DT_SOCK 
19      DT_WHT = 14 
20  # define DT_WHT DT_WHT 
21 }; 
View Code

  3、目录文件的操作函数——opendir、readdir、closedir;

opendir(打开目录)

 
相关函数
open,readdir,closedir,rewinddir,seekdir,telldir,scandir
表头文件
#include<sys/types.h>
#include<dirent.h>
定义函数
DIR * opendir(const char * name);
函数说明
opendir()用来打开参数name指定的目录,并返回DIR*形态的目录流,和open()类似,接下来对目录的读取和搜索都要使用此返回值。
返回值
成功则返回DIR* 型态的目录流,打开失败则返回NULL。
错误代码
EACCESS 权限不足
EMFILE 已达到进程可同时打开的文件数上限。
ENFILE 已达到系统可同时打开的文件数上限。
ENOTDIR 参数name非真正的目录
ENOENT 参数name 指定的目录不存在,或是参数name 为一空字符串。
ENOMEM 核心内存不足。

 

readdir(读取目录)

相关函数
open,opendir,closedir,rewinddir,seekdir,telldir,scandir
表头文件
#include<sys/types.h>
#include<dirent.h>
定义函数
struct dirent * readdir(DIR * dir);
函数说明
readdir()返回参数dir目录流的下个目录进入点。
结构dirent定义如下
struct dirent
{
ino_t d_ino;
ff_t d_off;
signed short int d_reclen;
unsigned char d_type;
har d_name[256;
};
d_ino 此目录进入点的inode
d_off 目录文件开头至此目录进入点的位移
d_reclen _name的长度,不包含NULL字符
d_type d_name 所指的文件类型
d_name 文件名
返回值
成功则返回下个目录进入点。有错误发生或读取到目录文件尾则返回NULL。
附加说明
EBADF参数dir为无效的目录流。

 

closedir(关闭目录)

 
相关函数
opendir
表头文件
#include<sys/types.h>
#include<dirent.h>
定义函数
int closedir(DIR *dir);
函数说明
closedir()关闭参数dir所指的目录流。
返回值
关闭成功则返回0,失败返回-1,错误原因存于errno 中。
错误代码
EBADF 参数dir为无效的目录流
范例
参考readir()。

   4、代码示例:

技术图片
 1 #include <stdio.h>
 2 #include <sys/types.h>
 3 #include <dirent.h>
 4 #include <string.h>
 5 #include <errno.h>
 6 
 7 #if 0
 8 struct dirent   
 9 {   
10   long d_ino; /* inode number 索引节点号 */       
11     off_t d_off; /* offset to this dirent 在目录文件中的偏移 */       
12     unsigned short d_reclen; /* length of this d_name 文件名长 */       
13     unsigned char d_type; /* the type of d_name 文件类型 */       
14     char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */  
15 } 
16 
17 // d_type表示档案类型:
18   
19 enum
20 { 
21     DT_UNKNOWN = 0,  //类型未知。少数文件系统会出现此函数不支持的文件类型,另一些则总是返回这个值。译者注:总之这个值是为了应对不兼容的文件系统而设置的;
22  # define DT_UNKNOWN DT_UNKNOWN 
23      DT_FIFO = 1, // 一个命名管道,或FIFO
24  # define DT_FIFO DT_FIFO 
25      DT_CHR = 2, // 字符设备
26  # define DT_CHR DT_CHR 
27      DT_DIR = 4, // 目录
28  # define DT_DIR DT_DIR 
29      DT_BLK = 6, // 块设备
30  # define DT_BLK DT_BLK 
31      DT_REG = 8, // 常规文件
32  # define DT_REG DT_REG 
33      DT_LNK = 10, // 符号链接
34  # define DT_LNK DT_LNK 
35      DT_SOCK = 12, // 套接字
36  # define DT_SOCK DT_SOCK 
37      DT_WHT = 14 
38  # define DT_WHT DT_WHT 
39 }; 
40 
41 #endif 
42 
43 void listDir(char *dir)
44 {
45     DIR *dp;
46     struct dirent *dirp;
47     char childpath[512];
48 
49     memset(childpath,0,sizeof(childpath));
50     if ((dp = opendir(dir)) == NULL)
51     {
52         printf("can‘t open the directory %s,Error = %s!\n",dir,strerror(errno));
53         return;
54     }
55     
56     while ((dirp = readdir(dp)) != NULL)
57     {
58         // printf("dir = %s,dir_type = %d,DT_DIR = %d\n",dirp->d_name,dirp->d_type,DT_DIR);
59         if (dirp->d_type == DT_DIR)
60         {
61             if (strcmp(dirp->d_name,".") == 0 || strcmp(dirp->d_name,"..") == 0)
62                 continue;
63             sprintf(childpath,"%s/%s",dir,dirp->d_name);
64             printf("childpath = %s\n",childpath);
65             listDir(childpath);
66         }    
67         else
68         {
69             printf("filename = %s\n",dirp->d_name);
70         }
71     }
72     closedir(dp);
73 }
74 
75 int main(int argc,char *argv[])
76 {
77     if (argc != 2)
78     {
79         printf("Usage: ls directory name!\n");
80         return -1;
81     }
82     listDir(argv[1]);
83     return 0;
84 }
View Code

 

基础练习1——ls的实现与递归

标签:das   size   lse   位移   type   接下来   number   hid   tor   

原文地址:https://www.cnblogs.com/ys6738-4271-3931/p/11784127.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!