假设在Linux下要訪问一个目录。

我们须要知道一下系统调用.

1.opendir(path); //注意path是绝对路径

2.ptr=readdir(dir);//dir 为opendir();正常打开的目录 DIR dir.假设弱国訪问dir下的全部目录后。readdir()返回NULL,struct dirent ptr; 记录了文件的基本内容

3.stat(file,&buf)//struct stat buf;//将file(文件的绝对路径)。的状态放入buf中

以下以一个小列子来说明,若和显示目录下文件的信息

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <dirent.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. int main(){
  7. DIR *dir;
  8. struct dirent *ptr;
  9. char path[20]="/";
  10. struct stat buf;
  11. if((dir=opendir(path))==NULL){//打开目录
  12. perror("error:");
  13. }else{
  14. while((ptr=readdir(dir))!=NULL){//读取目录下的内容
  15. char file[30]="/";
  16. strcpy(file+strlen(file),ptr->d_name);
  17. lstat(file,&buf);//获取文件的绝对路径
  18. printf("%s ",ptr->d_name);//输出文件名称
  19. if(S_ISDIR(buf.st_mode)){//假设文件是目录,输出DIR
  20. printf(" DIR\n");
  21. }else{
  22. printf(" \n");
  23. }
  24.  
  25. }
  26. closedir(dir);//关闭目录子
  27. }
  28. return 0;
  29. }

执行结果

显示了根文件夹下的情况.

2.若果要实现ls -R 的功能.

1.能够非常方便的递归訪问(可是系统栈有限有溢出可能)

2.我们用构造文件,文件夹树装结构.

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU2FwcGhpcmVTdGFydA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

a.我们能够以队列层次展开顺寻为.1,2,3,4,.....13;(对于整个文件系统若果用队列来存储的话,可能所需空间。不能得到满足,我们的程序可能无法获得这麽大的空间),而且顺序也不合理

b.我们建立局部(这里以完整的树为例,加上里面的free变为局部树),来实现所有先序的訪问.

1.分析我们对于一个文件夹,打开能够得到他的全部子文件夹,一次仅仅要我们获得一个根节点的位置,就可建立它与它的直接孩子的联系,在此时訪问这些孩子.

没有孩子

2.若没有不论什么孩子,且有右兄弟。那麽訪问有兄的的树.訪问它

3.没有孩子,没有有兄弟,那麽该节点的父亲节点为根的树已经所有訪问完成.此时若父亲节点有右孩子,那麽訪问它.

4.除2,3,且有父亲节点。那麽当前节点父亲节点作为当前节点,继续寻找知道出现1,2,就能够訪问,

有孩子

訪问首个孩子.

就这样能够用先序列訪问该树.

×在带吗运行中弱国端错说明堆当期那文件訪问权限不够×

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <fcntl.h>
  4. #include <stdlib.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <dirent.h>
  8. #include <string.h>
  9. char path[5000];//文件夹长度
  10. int plength=0;
  11. long c=0;
  12. char temppath[5000];
  13. typedef struct node {
  14. char name[82];//记录位置的信息path[plength]+current->name来获取完整路径信息
  15. struct node* child;
  16. struct node* brother;
  17. struct node* father;
  18. }*cbnode;
  19. cbnode getCbnode(){ //用于获得新的节点
  20. cbnode cb=(cbnode)malloc(sizeof(struct node));
  21. cb->child=cb->brother=cb->father=NULL;
  22. return cb;
  23. }
  24. cbnode list(const char * rootpath){//传递调用位置的操作,所要展开的文件树根节点
  25. DIR *dir=NULL;
  26. struct dirent *ptr=NULL;//文件夹的列表项
  27. struct stat buf;//获取文件加文件夹
  28. strcpy(path,rootpath);
  29. plength=strlen(path);//获取路径长度
  30. strcpy(temppath,path);//拷贝到当前路径情况
  31. cbnode root=NULL,current=NULL;
  32. root=getCbnode();//获取当前节点
  33. strcpy(root->name,rootpath);
  34. current=root;
  35. if((dir=opendir(current->name))==NULL){//初始给定非文件夹文件夹
  36. printf("no such file or direct! %s\n",current->name);
  37. return NULL;
  38. }
  39. while(10){
  40. int count=0;//当前訪问到第几个节点
  41. cbnode previous=NULL;//除了第一个节点,其它节点都有上个节点
  42. while((ptr=readdir(dir))!=NULL){//产生树遍历子文件夹输出
  43. strcpy(temppath+plength,ptr->d_name);
  44. temppath[plength+strlen(ptr->d_name)]='\0';//得到详细文件位置
  45. if(strcmp(ptr->d_name,".")&&strcmp(ptr->d_name,"..")){
  46. printf("%s\n",temppath);//打印文件名
  47. }
  48.  
  49. if(lstat(temppath,&buf)==-1){
  50. printf("stat error\n");
  51.  
  52. }
  53. if(S_ISDIR(buf.st_mode)&&strcmp(ptr->d_name,".")&&strcmp(ptr->d_name,"..")){
  54. cbnode cb=getCbnode();
  55. //printf("dirpath:%s\n",temppath);
  56. //printf("%s \n",temppath);
  57. strcpy(cb->name,ptr->d_name);
  58. strcat(cb->name,"/");
  59. cb->name[strlen(cb->name)]='\0';
  60. if(count==0){
  61. previous=cb;
  62. current->child=cb;
  63. cb->father=current;
  64. }else{ //创建孩子链
  65. previous->brother=cb;
  66. cb->father=previous->father;
  67. previous=cb;
  68. }
  69. count++;
  70. //printf("dir:%ld\n",c);
  71. }
  72. }
  73. closedir(dir);
  74. if(count==0){//假设该节点下没有子文件夹
  75.  
  76. while(10){
  77. if(current->brother){
  78. plength-=strlen(current->name);
  79. //free(current);
  80. current=current->brother;
  81. strcpy(path+plength,current->name);
  82. plength+=strlen(current->name);
  83. path[plength]='\0';
  84. strcpy(temppath,path);
  85. break;
  86. }else if(current->fathert->father->brother){
  87. plength-=(strlen(current->name)+strlen(current->father->name));
  88. //free(current);
  89. current=current->father->brother;
  90. strcpy(path+plength,current->name);
  91. plength+=strlen(current->name);
  92. path[plength]='\0';
  93. strcpy(temppath,path);
  94. break;
  95. }else if(current->fathert->father->brother==NULL){
  96. plength-=strlen(current->name);
  97. path[plength]='\0';
  98. // free(current);
  99. current=current->father;//寻找上个节点
  100. strcpy(temppath,path);
  101. }else if(current->father==NULL){
  102. return NULL;//訪问结束
  103. }else{
  104. printf("default\n");
  105. }
  106.  
  107. }
  108. dir=opendir(path);
  109. }else{
  110. current=current->child;
  111. strcpy(path+plength,current->name);//当前节点为最后一个节
  112. plength+=strlen(current->name);
  113. path[plength]='\0';
  114. strcpy(temppath,path);
  115. dir=opendir(path);
  116. }
  117. }
  118. }
  119. int main(int argc,char *argv[]){
  120. printf("%s\n",argv[1]);
  121. list(argv[1]);
  122. return 0;
  123. }
  124.  
  125. #include <stdio.h>
  126. #include <unistd.h>
  127. #include <fcntl.h>
  128. #include <stdlib.h>
  129. #include <sys/types.h>
  130. #include <sys/stat.h>
  131. #include <dirent.h>
  132. #include <string.h>
  133. char path[5000];//文件夹长度
  134. int plength=0;
  135. long c=0;
  136. char temppath[5000];
  137. typedef struct node {
  138. char name[82];//记录位置的信息path[plength]+current->name来获取完整路径信息
  139. struct node* child;
  140. struct node* brother;
  141. struct node* father;
  142. }*cbnode;
  143. cbnode getCbnode(){ //用于获得新的节点
  144. cbnode cb=(cbnode)malloc(sizeof(struct node));
  145. cb->child=cb->brother=cb->father=NULL;
  146. return cb;
  147. }
  148. cbnode list(const char * rootpath){//传递调用位置的操作,所要展开的文件树根节点
  149. DIR *dir=NULL;
  150. struct dirent *ptr=NULL;//文件夹的列表项
  151. struct stat buf;//获取文件加文件夹
  152. strcpy(path,rootpath);
  153. plength=strlen(path);//获取路径长度
  154. strcpy(temppath,path);//拷贝到当前路径情况
  155. cbnode root=NULL,current=NULL;
  156. root=getCbnode();//获取当前节点
  157. strcpy(root->name,rootpath);
  158. current=root;
  159. if((dir=opendir(current->name))==NULL){//初始给定非文件夹文件夹
  160. printf("no such file or direct! %s\n",current->name);
  161. return NULL;
  162. }
  163. while(10){
  164. int count=0;//当前訪问到第几个节点
  165. cbnode previous=NULL;//除了第一个节点。其它节点都有上个节点
  166. while((ptr=readdir(dir))!=NULL){//产生树遍历子文件夹输出
  167. strcpy(temppath+plength,ptr->d_name);
  168. temppath[plength+strlen(ptr->d_name)]='\0';//得到详细文件位置
  169. if(strcmp(ptr->d_name,".")&&strcmp(ptr->d_name,"..")){
  170. printf("%s\n",temppath);//打印文件名
  171. }
  172.  
  173. if(lstat(temppath,&buf)==-1){
  174. printf("stat error\n");
  175.  
  176. }
  177. if(S_ISDIR(buf.st_mode)&&strcmp(ptr->d_name,".")&&strcmp(ptr->d_name,"..")){
  178. cbnode cb=getCbnode();
  179. //printf("dirpath:%s\n",temppath);
  180. //printf("%s \n",temppath);
  181. strcpy(cb->name,ptr->d_name);
  182. strcat(cb->name,"/");
  183. cb->name[strlen(cb->name)]='\0';
  184. if(count==0){
  185. previous=cb;
  186. current->child=cb;
  187. cb->father=current;
  188. }else{ //创建孩子链
  189. previous->brother=cb;
  190. cb->father=previous->father;
  191. previous=cb;
  192. }
  193. count++;
  194. //printf("dir:%ld\n",c);
  195. }
  196. }
  197. closedir(dir);
  198. if(count==0){//假设该节点下没有子文件夹
  199.  
  200. while(10){
  201. if(current->brother){
  202. plength-=strlen(current->name);
  203. //free(current);
  204. current=current->brother;
  205. strcpy(path+plength,current->name);
  206. plength+=strlen(current->name);
  207. path[plength]='\0';
  208. strcpy(temppath,path);
  209. break;
  210. }else if(current->fathert->father->brother){
  211. plength-=(strlen(current->name)+strlen(current->father->name));
  212. //free(current);
  213. current=current->father->brother;
  214. strcpy(path+plength,current->name);
  215. plength+=strlen(current->name);
  216. path[plength]='\0';
  217. strcpy(temppath,path);
  218. break;
  219. }else if(current->fathert->father->brother==NULL){
  220. plength-=strlen(current->name);
  221. path[plength]='\0';
  222. // free(current);
  223. current=current->father;//寻找上个节点
  224. strcpy(temppath,path);
  225. }else if(current->father==NULL){
  226. return NULL;//訪问结束
  227. }else{
  228. printf("default\n");
  229. }
  230.  
  231. }
  232. dir=opendir(path);
  233. }else{
  234. current=current->child;
  235. strcpy(path+plength,current->name);//当前节点为最后一个节
  236. plength+=strlen(current->name);
  237. path[plength]='\0';
  238. strcpy(temppath,path);
  239. dir=opendir(path);
  240. }
  241. }
  242. }
  243. int main(int argc,char *argv[]){
  244. printf("%s\n",argv[1]);
  245. list(argv[1]);
  246. return 0;
  247. }

linux创建文件树,孩子兄弟树(或广义表),创建文件树及其訪问的更多相关文章

  1. UVa11732 "strcmp()" Anyone?(Trie树+孩子兄弟表示法)

    我的做法是先建字典树,统计每个结点出现次数和相同字符串个数,每个结点对答案的贡献就是2*C(次数,2),然后再分别讨论相同字符串和不同字符串对答案的贡献. 另外这题主要就是Trie树的孩子兄弟表示法: ...

  2. 如何使用PHP上传文件,上传图片,php上传教程,php表单文件上传教程

    使用PHP进行文件上传,主要使用到表单功能和PHP内置的$_FILES函数功能.接下来我们看如何实现PHP上传功能.例子效果图,此例子是在Mac下进行调试成功的. PHP上传图片文件的功能代码如下: ...

  3. [加入用户]解决useradd 用户后没有加入用户Home文件夹的情况,Linux改变文件或文件夹的訪问权限命令,linux改动用户password,usermod的ysuum安装包。飞

    usermod的yum安装包: shadow-utils 将nobody用户加入到nogroup 组: usermod -g nogroup nobody cat /etc/passwd|grep n ...

  4. 为什么 MySQL 索引要使用 B+树而不是其它树形结构?比如 B 树?

    一个问题? InnoDB一棵B+树可以存放多少行数据?这个问题的简单回答是:约2千万 为什么是这么多呢? 因为这是可以算出来的,要搞清楚这个问题,我们先从InnoDB索引数据结构.数据组织方式说起. ...

  5. SOLR对多个(关联)表创建索引

    又两天没写博客,关于SOLR的东西,写了一周了还没写完我也是醉了,毕竟会的东西真不多,周四晚上加班没写,周五晚上公司同事聚会也没写,今天在家,还是把最后的一点写完吧,我会的剩下的也就是一个对多个表创建 ...

  6. apache禁止訪问某些文件或文件夹的方法

    [apache配置禁止訪问] 1. 禁止訪问某些文件/文件夹 添加Files选项来控制,比方要不同意訪问 .inc 扩展名的文件,保护php类库: <Files ~ "\.inc$&q ...

  7. 选课 - 树型DP(孩子兄弟建树法)

    题目描述 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了 N(N<300)门的选修课程,每个学生可选课程的数量 M 是给定的.学生选修了这M门课并考核通 ...

  8. Linux下创建与解压tar, tar.gz和tar.bz2文件及压缩率对比 | 沉思小屋

    刚 在qq群里面一位仁兄问到文件压缩的命令,平时工作中大多用解压缩命令,要是遇到压缩就现查(这不是一个好习惯),于是整理下Linux下创建与解压 zip.tar.tar.gz和tar.bz2文件及他们 ...

  9. Linux编程 5 (目录重命名与移动mv,删除文件rm,目录创建mkdir删除rmdir,查看file,cat,more,tail,head)

    一. 文件重命名与移动(mv) 在linux中,重命名文件称为移动(moving).mv命令可以将文件和目录移动到另一个位置或重新命名. 1.1 使用mv重命名 下面在/usr/local下面创建一个 ...

随机推荐

  1. SQL Server 从数据库快照还原数据库

    语法: restore database db_name from database_snapshot  = 'db_snapshot_name'; ------------------------- ...

  2. android apk 导出(签名) is not translated in xx 代码混淆 反编译

    apk导出遇到问题 解决方式如下 1.导出步骤第一步 2.提示错误 3.解决 其余步骤参见: 代码混淆和数字签名(现在版本混淆) http://blog.csdn.net/moruna/article ...

  3. node配置运行环境变量;

    node express 在开发环境和生产环境运行的代码是不一样的, 通常是先配置好的,在开发环境运行一套代码,在生产环境运行另一套代码, 开发环境 development, 生产环境producti ...

  4. HDU Today(dijskra)

    HDU Today Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. SQL事务与并发

    1.Transaction(事务)是什么: 事务是作为单一工作单元而执行的一系列操作.包括增删查改. 2.事务的种类: 事务分为显示事务和隐式事务: 隐式事务:就是平常我们使用每一条sql 语句就是一 ...

  6. jQuery源码笔记——四

    each()实现 var jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ) ...

  7. Android Handler Leak

    转自:Android中使用Handler引发的内存泄露 在Activity中,经常会用到自定义的Handler来处理主线程收到的Message,但是ADT20以后,直接定义的如下定义的内部会有提示说这 ...

  8. SVN导出增量包的方法

    此方法是在svn1.7版本基础上进行的操作,其他版本没有验证 第一步.点击右键,选择“TortoiseSVN–> Show log”. 进入日志页面,如下图所示: 第二步.选择版本区间,右键选择 ...

  9. Extjs springmvc session 超时 处理

    如果你的项目使用ExtJS作为表现层,你会发现,SESSION超时控制将是一个问题.本文将就自己的经验,来解决这一问题,当然,解决问题并非只有一种方法,我只是提出我的方法.首先,做超时控制,必需使用过 ...

  10. js监听input等表单输入框的变化事件oninput

    js监听input等表单输入框的变化事件oninput,手机页面开发中使用到文本框textarea输入字符监听文本框变化计算还可以输入多少字符,如果使用onkeyup的话是无法监听到输入法输入的文本变 ...