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

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

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

  2、用到的结构体——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 文件名长 */   
unsigned char d_type; /* the type of d_name 文件类型 */   
char d_name [NAME_MAX+]; /* file name (null-terminated) 文件名,最长255字符 */
}

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

 enum
{
DT_UNKNOWN = , //类型未知。少数文件系统会出现此函数不支持的文件类型,另一些则总是返回这个值。译者注:总之这个值是为了应对不兼容的文件系统而设置的;
# define DT_UNKNOWN DT_UNKNOWN
DT_FIFO = , // 一个命名管道,或FIFO
# define DT_FIFO DT_FIFO
DT_CHR = , // 字符设备
# define DT_CHR DT_CHR
DT_DIR = , // 目录
# define DT_DIR DT_DIR
DT_BLK = , // 块设备
# define DT_BLK DT_BLK
DT_REG = , // 常规文件
# define DT_REG DT_REG
DT_LNK = , // 符号链接
# define DT_LNK DT_LNK
DT_SOCK = , // 套接字
# define DT_SOCK DT_SOCK
DT_WHT =
# define DT_WHT DT_WHT
};

  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、代码示例:

 #include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <errno.h> #if 0
struct dirent
{
  long d_ino; /* inode number 索引节点号 */   
off_t d_off; /* offset to this dirent 在目录文件中的偏移 */   
unsigned short d_reclen; /* length of this d_name 文件名长 */   
unsigned char d_type; /* the type of d_name 文件类型 */   
char d_name [NAME_MAX+]; /* file name (null-terminated) 文件名,最长255字符 */
} // d_type表示档案类型: enum
{
DT_UNKNOWN = , //类型未知。少数文件系统会出现此函数不支持的文件类型,另一些则总是返回这个值。译者注:总之这个值是为了应对不兼容的文件系统而设置的;
# define DT_UNKNOWN DT_UNKNOWN
DT_FIFO = , // 一个命名管道,或FIFO
# define DT_FIFO DT_FIFO
DT_CHR = , // 字符设备
# define DT_CHR DT_CHR
DT_DIR = , // 目录
# define DT_DIR DT_DIR
DT_BLK = , // 块设备
# define DT_BLK DT_BLK
DT_REG = , // 常规文件
# define DT_REG DT_REG
DT_LNK = , // 符号链接
# define DT_LNK DT_LNK
DT_SOCK = , // 套接字
# define DT_SOCK DT_SOCK
DT_WHT =
# define DT_WHT DT_WHT
}; #endif void listDir(char *dir)
{
DIR *dp;
struct dirent *dirp;
char childpath[]; memset(childpath,,sizeof(childpath));
if ((dp = opendir(dir)) == NULL)
{
printf("can't open the directory %s,Error = %s!\n",dir,strerror(errno));
return;
} while ((dirp = readdir(dp)) != NULL)
{
// printf("dir = %s,dir_type = %d,DT_DIR = %d\n",dirp->d_name,dirp->d_type,DT_DIR);
if (dirp->d_type == DT_DIR)
{
if (strcmp(dirp->d_name,".") == || strcmp(dirp->d_name,"..") == )
continue;
sprintf(childpath,"%s/%s",dir,dirp->d_name);
printf("childpath = %s\n",childpath);
listDir(childpath);
}
else
{
printf("filename = %s\n",dirp->d_name);
}
}
closedir(dp);
} int main(int argc,char *argv[])
{
if (argc != )
{
printf("Usage: ls directory name!\n");
return -;
}
listDir(argv[]);
return ;
}

最新文章

  1. ax Mail
  2. javaweb常见问题解决
  3. guava函数式编程
  4. eclipse 闪退
  5. Threading.Tasks 简单的使用
  6. leetcode - Merge Sorted Array (run time beats 100.00% of cpp submissions.)
  7. AJAX 异步交互基本总结
  8. ios9 之后,Xcode7不推荐使用UIAlertView,改用UIAlertController+UIAlertAction(按钮)
  9. 不等高cell的搭建(一)
  10. 队列 - 从零开始实现by C++
  11. 机器学习第三课(EM算法和高斯混合模型)
  12. [ATL/WTL]_[0基础]_[CBitmap复制图片-截取图片-平铺图片]
  13. 安卓获取Assets目录下的资源
  14. 关于线程和junit注入失败的问题
  15. 设置ImageView显示的图片铺满全屏
  16. React-报错Warning:setState(...)on anunmounted component
  17. 京东618:Docker扛大旗,弹性伸缩成重点 (2015-06-23)
  18. Spring的后处理器-BeanPostProcessor跟BeanFactoryPostProcessors
  19. QXcbConnection: Could not connect to display
  20. Java基础知识_毕向东_Java基础视频教程笔记(14-18集合框架)

热门文章

  1. 【Oracle】SQL语句优化
  2. java并发之内存模型
  3. vue3.0的安装使用
  4. iptables详解之filter
  5. 引入jar包到本地仓库方法
  6. 攻防世界(XCTF)WEB(进阶区)write up(二)
  7. phpstudy后门rce批量利用脚本
  8. shark恒破解笔记4-API断点GetPrivateProfileStringA
  9. 小白学 Python(4):变量基础操作
  10. 冰释前嫌——转入Android Studio与连接手机无法识别问题