linux创建文件树,孩子兄弟树(或广义表),创建文件树及其访问

如果在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中

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

#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(){
        DIR *dir;
        struct dirent *ptr;
        char path[20]="/";
        struct stat buf;
        if((dir=opendir(path))==NULL){//打开文件夹
                perror("error:");
        }else{
                while((ptr=readdir(dir))!=NULL){//读取文件夹下的内容
                        char file[30]="/";
                        strcpy(file+strlen(file),ptr->d_name);
                        lstat(file,&buf);//获取文件的绝对路径
                        printf("%s  ",ptr->d_name);//输出文件名
                        if(S_ISDIR(buf.st_mode)){//如果文件是文件夹,输出DIR
                                printf(" DIR\n");
                        }else{
                                printf(" \n");
                        }
                        
                }
                closedir(dir);//关闭文件夹子
        }
        return 0;
}
运行结果

显示了根目录下的情况.

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

1.可以很方便的递归访问(但是系统栈有限有溢出可能)

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

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

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

1.分析我们对于一个目录,打开可以得到他的所有子目录,一次只要我们获得一个根节点的位置,就可建立它与它的直接孩子的联系,在此时访问这些孩子.

没有孩子

2.若没有任何孩子,且有右兄弟,那麽访问有兄的的树.访问它

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

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

有孩子

访问首个孩子.


就这样可以用先序列访问该树.

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

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
char path[5000];//目录长度
int plength=0;
long c=0;
char temppath[5000];
typedef struct node {
        char name[82];//记录位置的信息path[plength]+current->name来获取完整路径信息
        struct node* child;
        struct node* brother;
        struct node* father;
}*cbnode;
cbnode getCbnode(){ //用于获得新的节点
        cbnode cb=(cbnode)malloc(sizeof(struct node));
        cb->child=cb->brother=cb->father=NULL;
        return cb;
}
cbnode list(const char * rootpath){//传递调用位置的操作,所要展开的文件树根节点
    DIR *dir=NULL;
        struct dirent *ptr=NULL;//文件夹的列表项
        struct stat buf;//获取文件加目录
        strcpy(path,rootpath);
        plength=strlen(path);//获取路径长度
        strcpy(temppath,path);//复制到当前路径情况
        cbnode root=NULL,current=NULL;
        root=getCbnode();//获取当前节点
        strcpy(root->name,rootpath);
        current=root;
        if((dir=opendir(current->name))==NULL){//初始给定非目录文件夹
                printf("no such file or direct! %s\n",current->name);
                return NULL;
        }
        while(10){
                int count=0;//当前访问到第几个节点
                cbnode previous=NULL;//除了第一个节点,其他节点都有上个节点
                while((ptr=readdir(dir))!=NULL){//产生树遍历子目录输出
                        strcpy(temppath+plength,ptr->d_name);
                        temppath[plength+strlen(ptr->d_name)]='\0';//得到具体文件位置
                        if(strcmp(ptr->d_name,".")&&strcmp(ptr->d_name,"..")){
                    printf("%s\n",temppath);//打印文件名称
                        }
                        
            if(lstat(temppath,&buf)==-1){
                                printf("stat error\n");
                                
                        }
                        if(S_ISDIR(buf.st_mode)&&strcmp(ptr->d_name,".")&&strcmp(ptr->d_name,"..")){
                              cbnode cb=getCbnode();
                              //printf("dirpath:%s\n",temppath);
                  //printf("%s \n",temppath);
                              strcpy(cb->name,ptr->d_name);
                              strcat(cb->name,"/");
                  cb->name[strlen(cb->name)]='\0';
                              if(count==0){      
                                        previous=cb;
                                        current->child=cb;
                                        cb->father=current;
                              }else{    //创建孩子链
                                        previous->brother=cb;
                                        cb->father=previous->father;
                                        previous=cb;
                              }
                              count++;
                  //printf("dir:%ld\n",c);
                    }
              }
              closedir(dir);
              if(count==0){//如果该节点下没有子目录
                        
            while(10){
                                if(current->brother){       
                                    plength-=strlen(current->name);
                    //free(current);
                    current=current->brother;
                                    strcpy(path+plength,current->name);
                                    plength+=strlen(current->name);
                                    path[plength]='\0';
                                    strcpy(temppath,path);
                                    break;
                                }else if(current->father&¤t->father->brother){
                                         plength-=(strlen(current->name)+strlen(current->father->name));
                         //free(current);
                                         current=current->father->brother;
                                         strcpy(path+plength,current->name);
                                         plength+=strlen(current->name);
                                         path[plength]='\0';
                                         strcpy(temppath,path);
                                         break;
                                }else if(current->father&¤t->father->brother==NULL){
                                         plength-=strlen(current->name);
                                         path[plength]='\0';
                //     free(current);
                     current=current->father;//寻找上个节点
                                         strcpy(temppath,path);
                                }else if(current->father==NULL){
                                         return NULL;//访问结束
                                }else{
                     printf("default\n");
                }
                                
                        }
                        dir=opendir(path);
                }else{  
                        current=current->child;
                        strcpy(path+plength,current->name);//当前节点为最后一个节
                        plength+=strlen(current->name);
                        path[plength]='\0';
            strcpy(temppath,path);
                        dir=opendir(path);
                }
        }
}
int main(int argc,char *argv[]){
        printf("%s\n",argv[1]);
        list(argv[1]);
        return 0;
}



#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
char path[5000];//目录长度
int plength=0;
long c=0;
char temppath[5000];
typedef struct node {
        char name[82];//记录位置的信息path[plength]+current->name来获取完整路径信息
        struct node* child;
        struct node* brother;
        struct node* father;
}*cbnode;
cbnode getCbnode(){ //用于获得新的节点
        cbnode cb=(cbnode)malloc(sizeof(struct node));
        cb->child=cb->brother=cb->father=NULL;
        return cb;
}
cbnode list(const char * rootpath){//传递调用位置的操作,所要展开的文件树根节点
    DIR *dir=NULL;
        struct dirent *ptr=NULL;//文件夹的列表项
        struct stat buf;//获取文件加目录
        strcpy(path,rootpath);
        plength=strlen(path);//获取路径长度
        strcpy(temppath,path);//复制到当前路径情况
        cbnode root=NULL,current=NULL;
        root=getCbnode();//获取当前节点
        strcpy(root->name,rootpath);
        current=root;
        if((dir=opendir(current->name))==NULL){//初始给定非目录文件夹
                printf("no such file or direct! %s\n",current->name);
                return NULL;
        }
        while(10){
                int count=0;//当前访问到第几个节点
                cbnode previous=NULL;//除了第一个节点,其他节点都有上个节点
                while((ptr=readdir(dir))!=NULL){//产生树遍历子目录输出
                        strcpy(temppath+plength,ptr->d_name);
                        temppath[plength+strlen(ptr->d_name)]='\0';//得到具体文件位置
                        if(strcmp(ptr->d_name,".")&&strcmp(ptr->d_name,"..")){
                    printf("%s\n",temppath);//打印文件名称
                        }
                        
            if(lstat(temppath,&buf)==-1){
                                printf("stat error\n");
                                
                        }
                        if(S_ISDIR(buf.st_mode)&&strcmp(ptr->d_name,".")&&strcmp(ptr->d_name,"..")){
                              cbnode cb=getCbnode();
                              //printf("dirpath:%s\n",temppath);
                  //printf("%s \n",temppath);
                              strcpy(cb->name,ptr->d_name);
                              strcat(cb->name,"/");
                  cb->name[strlen(cb->name)]='\0';
                              if(count==0){      
                                        previous=cb;
                                        current->child=cb;
                                        cb->father=current;
                              }else{    //创建孩子链
                                        previous->brother=cb;
                                        cb->father=previous->father;
                                        previous=cb;
                              }
                              count++;
                  //printf("dir:%ld\n",c);
                    }
              }
              closedir(dir);
              if(count==0){//如果该节点下没有子目录
                        
            while(10){
                                if(current->brother){       
                                    plength-=strlen(current->name);
                    //free(current);
                    current=current->brother;
                                    strcpy(path+plength,current->name);
                                    plength+=strlen(current->name);
                                    path[plength]='\0';
                                    strcpy(temppath,path);
                                    break;
                                }else if(current->father&¤t->father->brother){
                                         plength-=(strlen(current->name)+strlen(current->father->name));
                         //free(current);
                                         current=current->father->brother;
                                         strcpy(path+plength,current->name);
                                         plength+=strlen(current->name);
                                         path[plength]='\0';
                                         strcpy(temppath,path);
                                         break;
                                }else if(current->father&¤t->father->brother==NULL){
                                         plength-=strlen(current->name);
                                         path[plength]='\0';
                //     free(current);
                     current=current->father;//寻找上个节点
                                         strcpy(temppath,path);
                                }else if(current->father==NULL){
                                         return NULL;//访问结束
                                }else{
                     printf("default\n");
                }
                                
                        }
                        dir=opendir(path);
                }else{  
                        current=current->child;
                        strcpy(path+plength,current->name);//当前节点为最后一个节
                        plength+=strlen(current->name);
                        path[plength]='\0';
            strcpy(temppath,path);
                        dir=opendir(path);
                }
        }
}
int main(int argc,char *argv[]){
        printf("%s\n",argv[1]);
        list(argv[1]);
        return 0;
}








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值