假设在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.我们用构造文件,文件夹树装结构.

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,就能够訪问,

有孩子

訪问首个孩子.

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

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

#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;
}

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. mysql 插入前 锁表问题

    $dbh = DBI->connect("dbi:mysql:database=$db_name;host=$ip;port=3306",$user,$passwd,{ Ra ...

  2. 理解Unity加载和内存管理

    转自:http://game.ceeger.com/forum/read.php?tid=4394#info Unity里有两种动态加载机制:一是Resources.Load,一是通过AssetBun ...

  3. 经典排序算法(Java实现)

    以下程序均将数据封装于DataWrap数据包装类中,如下所示: //数据包装类 class DataWrap implements Comparable<DataWrap> { int d ...

  4. AndroidUI 视图动画-自定义动画效果 (Animation)

    如果Android提供的四种动画 效果 和混合动画效果 不能够 满足需求的话,可以使用自定义动画效果 : 新建一个类CustomAnimation 使其继承自 android.view.animati ...

  5. poj 3764 The xor-longest Path(字典树)

    题目链接:poj 3764 The xor-longest Path 题目大意:给定一棵树,每条边上有一个权值.找出一条路径,使得路径上权值的亦或和最大. 解题思路:dfs一遍,预处理出每一个节点到根 ...

  6. mysql数据库日期是varchar类型的时间比较查询

     单纯的字符串比较结果不精确. select * from 表明 where times> '2088/12/8 10:02:40' (×) 转换函数如下(数据库为varchar): selec ...

  7. HBASE学习笔记--概述

    定义: HBase是一个分布式的.面向列的开源数据库,HBase是Google Bigtable的开源实现,它利用Hadoop HDFS作为其文件存储系统,利用Hadoop MapReduce来处理H ...

  8. asp.net BulletedList绑定数据及vs2013添加数据库文件

    首先是在网页中添加一个BulletedList控件,通过编辑项来添加显示的数据. 这是一种添加数据的方式,另一种是通过绑定数据源来实现.在此之前,要先添加一个sql server数据库: 点开右键菜单 ...

  9. Java 基本日期类使用(一)

    一.java.util.Date Date表示特定的瞬间,精确到毫秒,其子类有Date.Time.Timestap.默认情况下输出的Date对象为:Mon Oct 13 17:48:47 CST 20 ...

  10. VBA基础知识———常用语句

    语句一:if判断语句 Sub 判断1() '单条件判断 If Range("a1").Value > 0 Then Range("b1") = " ...