您的位置:首页 > 运维架构 > Linux

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

2016-03-10 14:45 639 查看
假设在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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: