一个文件目录遍历的算法结构实现

该文章介绍了一种使用链表实现的Windows系统下文件遍历算法,避免了递归,能处理任意深度的目录结构。算法利用单向链表处理同级目录,双向链表处理父子目录关系,且经过测试无内存泄漏。主要函数包括DirList用于遍历目录和DelTree用于销毁目录树。
摘要由CSDN通过智能技术生成

最近做一个工具时,需要一个文件遍历算法,网上寻觅无果后,自己动手写了一个,本算法用了一个单向链表用来实现同级目录移动,用一个双向链表用来实现父子目录的下行和递归,摒弃了递归函数,因此不限制目录层数和子目录数量,适用所有的目录情况,所以拿出来分享一下,经反复测试,无内存泄露,需要的人就可以直接拿过去用了:

#include <windows.h>

typedef struct dirs     //目录单元结构
{
    char *file;    //目录名
    struct dirs *father; //父目录指针
    struct dirs  *child;//子目录指针
    struct dirs *next;//下一个同级目录指针
} dirs_t;

void DelTree(dirs_t *peer)   //销毁目录树函数
{
    dirs_t *p=peer;
    dirs_t *tmp;
    while(p->father!=NULL||p->child!=NULL)
    {
        if(p->child!=NULL)
        {
            p=p->child;
            p->father->child=p->next;
            // continue;

        }
        else if(p->child==NULL&&p->father!=NULL)
        {
            tmp=p;
            if(p->next!=NULL)
            {
                p=p->next;
                p->father=p->next;
            }
            else
            {
                p=p->father;
                p->child=NULL;

            }
            free(tmp->file);
            free(tmp);
        }
    }
    free(p);
}

int DirList(char *topdir)                       //功能函数
{
    dirs_t *top,*p,*pfather,*tmp;

    WIN32_FIND_DATA FindFileData;
    HANDLE hFind = INVALID_HANDLE_VALUE;
    int firstflag;   //下行标志

    char *pathname;
    int  pathsize;
    char *ptmp;
    int num=0;

    top=(dirs_t *)malloc(sizeof(dirs_t));
    if(top==NULL)
        return -1;

    top->file=topdir;
    top->father=NULL;
    top->next=NULL;
    top->child=top;
    p=top;
    do
    {
        firstflag=0;
        if(p->father!=NULL&&p->child==NULL)//上行判断
        {
            if(p->next!=NULL)
            {
                tmp=p;
                p=p->next;
                p->father->child=p->next;
                free(tmp->file);
                free(tmp);
            }
            else
            {
                tmp=p;
                p=p->father;
                p->child=NULL;
                free(tmp->file);
                free(tmp);

                continue;
            }
        }
        tmp=p;
        pathsize=strlen(top->file);
        while(tmp!=top)
        {

            pathsize+=strlen(tmp->file);
            pathsize++;
            tmp=tmp->father;

        }
        pathname=(char *)malloc((pathsize+6)*sizeof(char));
        if(pathname==NULL)
        {
            DelTree(p);
            return -1;
        }
        tmp=p;
        strcpy(pathname,top->file);
        ptmp=pathname+pathsize;
        while(tmp!=top)
        {
            ptmp=ptmp-strlen(tmp->file);
            memcpy(ptmp,tmp->file,strlen(tmp->file));


            memcpy(ptmp-1,"\\",1);
            ptmp--;
            tmp=tmp->father;

        }
        pathname[pathsize]='\0';
        strcat(pathname,"\\*.*");
        hFind = FindFirstFile(pathname, &FindFileData);
        if(hFind!=INVALID_HANDLE_VALUE)
        {
            if(strcmp(FindFileData.cFileName,".")!=0&&strcmp(FindFileData.cFileName,"..")!=0)
            {
                if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                {

                    p->child=(dirs_t *)malloc(sizeof(dirs_t));
                    if(p->child==NULL)
                    {
                        DelTree(p);
                        FindClose(hFind);
                        free(pathname);
                        return -1;
                    }
                    pfather=p;
                    p=p->child;
                    p->next=NULL;
                    p->child=p;
                    p->father=pfather;
                    firstflag=1;
                    p->file=(char *)malloc((strlen(FindFileData.cFileName)+1)*sizeof(char));
                    if(p->file==NULL)
                    {
                        DelTree(p);
                        FindClose(hFind);
                        free(pathname);
                        return -1;
                    }
                    strcpy(p->file,FindFileData.cFileName);
                }
                else
                {
                    printf("%s\n",FindFileData.cFileName);
                    num++;
                }
            }
            while(FindNextFile(hFind, &FindFileData))
            {
                if(strcmp(FindFileData.cFileName,".")!=0&&strcmp(FindFileData.cFileName,"..")!=0)
                {
                    if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                    {
                        if(!firstflag)                                             //下行标志
                        {
                            p->child=(dirs_t *)malloc(sizeof(dirs_t));
                            if(p->child==NULL)
                            {
                                DelTree(p);
                                FindClose(hFind);
                                free(pathname);
                                return -1;
                            }
                            pfather=p;
                            p=p->child;
                            p->father=pfather;
                            firstflag=1;
                        }
                        else
                        {
                            p->next=(dirs_t *)malloc(sizeof(dirs_t));
                            if(p->next==NULL)
                            {
                                DelTree(p);
                                FindClose(hFind);
                                free(pathname);
                                return -1;
                            }

                            p=p->next;

                        }
                        p->father=pfather;
                        p->next=NULL;
                        p->child=p;
                        p->file=(char *)malloc((strlen(FindFileData.cFileName)+1)*sizeof(char));
                        if(p->file==NULL)
                        {
                            DelTree(p);
                            FindClose(hFind);
                            free(pathname);
                            return -1;
                        }
                        strcpy(p->file,FindFileData.cFileName);
                    }
                    else
                    {
                        printf("%s\n",FindFileData.cFileName);
                        num++;
                    }
                }
            }
        }
        FindClose(hFind);
        free(pathname);
        if(firstflag!=0)  //进入子目录
        {
            //  updownflag=0;
            p=p->father->child;
            p->father->child=p->next;
        }
        else if(firstflag==0&&p->father!=NULL)
        {
            tmp=p;
            if(p->next==NULL) //进入父目录
            {
                p=p->father;
                p->child=NULL;
            }
            else  //进入同级目录
            {

                p=p->next;
                p->father->child=p->next;

            }
            free(tmp->file);
            free(tmp);
        }

        else
        {
            break;
        }

    }
    while(p->father!=NULL||p->child!=NULL);
    free(top);
    printf("共%d个文件\n",num);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值