Linux显示文件树形结构信息的小程序

本文介绍了一个使用C语言编写的程序,该程序能够递归地遍历指定目录及其子目录,并以树状结构显示文件夹和文件。通过深度优先搜索的方式,程序实现了对目录结构的清晰展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

// 最大目录深度
#define MAX_DIR_DEPTH   64
#define __LEN           4
#define MAX_FILE_LEN    256
#define MAX_LEN         ((64 * __LEN) +  MAX_FILE_LEN)
#define MAX_PATH_LEN    (64 * 32)

void print_dir(const char * file_name, int depth, char *show_c, struct dirent *pDirRes)
{
    int i;
    int pos = depth * __LEN;
    
    show_c[pos - __LEN+1]  = '|';
    for(i = 0; i < __LEN-1;  i++) show_c[pos - i] = '-';
    show_c[pos+1] = '\0';

    printf("%s%s\n", show_c, file_name);
    if(!pDirRes) {
        show_c[pos-__LEN + 1] = ' ';
    }
    
    for(i = 0; i < __LEN-1;  i++) show_c[pos - i] = ' ';
}

void clear_c(int depth, char *show_c )
{
    show_c[(depth-1) * __LEN + 1] = ' ';
}

int is_last_dir(DIR *pDir)
{
    return 0;
}

int __tree_dir(const char* dirname, int depth, char *show_c)
{
    DIR     *pDir;
    struct stat file_stat;
    struct dirent diren;
    struct dirent *pDirRes;
    char *tmpname;

    if(depth >= MAX_DIR_DEPTH) return -1;

    tmpname = malloc(MAX_PATH_LEN);
    if(!tmpname) return -1;

    /* open dir */
    pDir = opendir(dirname);
    if(NULL == pDir){
        printf("%s %s\n", dirname , strerror(errno)); 
        goto ERR;
    }

    do{              
         if(readdir_r(pDir, &diren, &pDirRes)){
            closedir(pDir);
            printf("%s\n", strerror(errno));
            goto ERR;
        }

        if(!pDirRes) { clear_c(depth, show_c); break; }

        if(strcmp(".", diren.d_name) == 0 || strcmp("..", diren.d_name)==0) continue;

        snprintf(tmpname, MAX_PATH_LEN, "%s/%s", dirname , diren.d_name);
        bzero(&file_stat, sizeof(file_stat));

        if(-1 == stat(tmpname, &file_stat)){
            closedir(pDir);
            printf("%s\n", strerror(errno));
            goto ERR;
        }

        print_dir(diren.d_name, depth, show_c, pDirRes);

        if(S_ISDIR(file_stat.st_mode)){
//            if(is_last_dir(pDir)) clear(depth, show_c);
            __tree_dir(tmpname, depth+1, show_c);
        }

    }while(NULL != pDirRes);

    closedir(pDir);
    free(tmpname);
    return 0;

ERR:
    free(tmpname);
    return -1;

}

int tree_dir(const char* path)
{
    char *show_c ;
    int ret;

    show_c = malloc(MAX_LEN);

    if(!show_c) return errno;
    memset(show_c, ' ', MAX_LEN);

    ret = __tree_dir(path, 1, show_c);

    free(show_c);
    return ret;
}

#define VERSION    "version v1.0 : created by Dremi"

int main(int argc, char**argv)
{
    if(argc < 2) return -1;

    if(strcmp("-v", argv[1]) == 0){
        printf("%s\n", VERSION);
        return 0;
    }

    return tree_dir(argv[1]);
}


 版本2:

 
int __tree_dir(const char* dirname, int depth, char *show_c)
{
    DIR     *pDir;
    struct stat file_stat;
    struct dirent diren;
    struct dirent *pDirRes;
    char  *olddir;

    if(depth >= MAX_DIR_DEPTH) return -1;

    olddir= malloc(MAX_FILE_LEN);
    if(!olddir) return -1;

    getcwd(olddir, MAX_FILE_LEN);

    if(chdir(dirname)){
		free(olddir);
        printf("%s %s\n", dirname, strerror(errno));
        return -1;
    }

    /* open dir */
    pDir = opendir("./");
    if(NULL == pDir){
		free(olddir);
        printf("%s %s\n", dirname , strerror(errno)); 
        return -1;
    }

    do{              
         if(readdir_r(pDir, &diren, &pDirRes)){
            closedir(pDir);
			free(olddir);
            printf("%s\n", strerror(errno));
            return -1;
        }

        if(!pDirRes) { clear_c(depth, show_c); break; }

        if(strcmp(".", diren.d_name) == 0 || strcmp("..", diren.d_name)==0) continue;

        bzero(&file_stat, sizeof(file_stat));

        if(-1 == stat(diren.d_name, &file_stat)){
            closedir(pDir);
			free(olddir);
            printf("%s\n", strerror(errno));
            return -1;
        }

        print_dir(diren.d_name, depth, show_c, pDirRes);

        if(S_ISDIR(file_stat.st_mode)){
//            if(is_last_dir(pDir)) clear(depth, show_c);
            __tree_dir(diren.d_name, depth+1, show_c);
        }

    }while(NULL != pDirRes);

    closedir(pDir);
    chdir(olddir);
    free(olddir);
    return 0;
}


效果如下:

 

 |---main_x64
 |---main_x86
 |---test_asm
 |   |---a.out
 |   |---asm.c
 |   |---get_reg.c
 |---test_dll
 |   |---main
 |   |---mk_dll.sh
 |   |---test_dll1.c
 |   |---test_dll1.h
 |   |---test_dll2.c
 |   |---test_dll2.h
 |   |---libtestdll1.so
 |   |---libtestdll2.so
 |   |---main.c
 |---test_log
 |   |---test_log.c
 |   |---a.out
 |---test1.c
 |---test2.c
 |---com_prog


 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值