C语言C++,dirent自创ddir结构体,实现更便捷的文件夹 *** 作

C语言C++,dirent自创ddir结构体,实现更便捷的文件夹 *** 作,第1张

C语言,C++的文件夹 *** 作常见的只有opendir(),readdir(),closedir(),rewinddir(),在中有DIR,struct dirent两个结构体,对系统fcntl进行复杂 *** 作,最后就给出个d_name名字能看懂(linux还有d_type)

 

每次使用dirent时常常需要把路径拼接起来,跳过最前面的两个“文件夹”:.(本身)和..(上级文件夹),windows还需要stat判断文件类型。

这样复杂的处理代码,用一次dirent就得写一次,还很冗余,散架易错。我们需要一套半自动处理结构,简化代码,减轻应用层负担。于是我个人写了ddir包装体,实现一键拼路径、调点点、判断类型。

 

struct _ddir {

  char* _path; 含完整路径结果

  int _catPos; strcpy位置

  short _flag;

  short d_type; windows还能算type

  char* d_name; 与struct dirent同名兼容,放心替换

  DIR* _dir;

};

typedef struct _ddir ddir;

 

常见的dirent使用方法如下:

void func(void)(整体标记)

{ const char* pathdir="/storage/emulated/0/";(斜杠结尾)

char pathbuf[256];

strcpy(pathbuf,pathdir);

strcat(pathbuf,ent->d_name);

然后pathbuf才是完整路径,才能用。

对于Windows,struct dirent中没有d_type,难以区分文件还是文件夹,就要stat(),毕竟dirent全称是directory entry(文件夹入口)。

struct stat st;

if(stat(pathbuf,&st)==0)

{ if(S_ISDIR(st.st_mode)) type=4 //文件夹

  if(S_ISREG(st.st_mode)) type=8 //文件

} ...

}

我的ddir半自动工作原理:

void* myreaddir(x)

{ retptr=readdir(x);

  func();

  return retptr;

}

 

这就叫包装,使得将来的功能使用更简洁,这就值得。自己动手,丰衣足食。于是我把自创源码免费分享给大家,用就拿走。欢迎讨论意见,给变量取个更好听的名字。

 

如果对您有帮助,点个赞可以让更多人看到~

 

#ifndef _DDIR_H //Writer: Dexam
#define _DDIR_H //Date: 2022.4.23
#include
#include //malloc()
#include //strcpy(),strlen()
#include //path length < DDIR_PATHSIZE
//windows: #include type 4,8

struct _ddir {
  char* _path;
  int _catPos;
  short _flag;
  short d_type;
  char* d_name;
  DIR* _dir;
};
typedef struct _ddir ddir;

#define DDIR_PATHSIZE 256

#define _DDIR_ONDIR 0x01
#define _DDIR_SET 0x02
#define _DDIR_EOF 0x04

#define deod(f) (_Bool)((f)->_flag&_DDIR_EOF)

ddir* ddiropen(const char*);
ddir* ddirwrap(DIR*,const char*);
int ddirclose(ddir*);
ddir* ddirread(ddir*);
//use as readdir() p->d_name, p->d_type

int ddirget(ddir*);
//return item type, ".",".." skipped
/* errno for path overflow:
14: Bad address
36: File name too long
*/

#if 1 //Linux:
#define DIR_SLASH '/'
int ddirtype(ddir* dp,struct dirent* ent)
{    return ent->d_type;}
#else //Windows:
#define DIR_SLASH '\\'
int ddirtype(ddir* dp,struct dirent* ent)
{    int x,ftype=0;
    struct stat st;
    if(stat(dp->_path,&st)??) {
        x=st.st_mode;
        if(S_ISDIR(x)) ftype=4;
        else if(S_ISREG(x)) ftype=8;
        else if(S_ISLNK(x)) ftype=10;
    }
    return ftype;
}
#endif

ddir* ddirwrap(DIR* fdir,const char* path)
{
    int catPos;
    ddir* dp=NULL;
    char* pathbuf=NULL;
    if(fdir!=NULL)
        dp=(ddir*)malloc(sizeof(ddir));
    if(dp!=NULL)
        pathbuf=(char*)malloc(DDIR_PATHSIZE);
    if(pathbuf==NULL) {
        free(dp);
        return NULL;
    }
    if(path!=NULL) {
        if(path[0]==0||strlen(path)>= DDIR_PATHSIZE)
            path=NULL;
    }
    if(path!=NULL) {
        catPos=strlen(strcpy(pathbuf,path));
        if(pathbuf[catPos-1]!=DIR_SLASH) {
            pathbuf[catPos]=DIR_SLASH;
            pathbuf[catPos+1]=0;
            catPos++;
        }
    } else {
        pathbuf[0]=DIR_SLASH;
        pathbuf[1]=0;
        catPos=1;
    }
    dp->_path=pathbuf;
    dp->_catPos=catPos;
    dp->d_type=0;
    dp->d_name=NULL;
    dp->_dir=fdir;
    dp->_flag=_DDIR_ONDIR|_DDIR_SET;
    return dp;
}

ddir* ddiropen(const char* path)
{
    DIR* fdir=NULL;
    ddir* dp=NULL;
    fdir=opendir(path);
    if(fdir!=NULL) {
        dp=ddirwrap(fdir,path);
        if(dp==NULL)
            closedir(fdir);
    }
    return dp;
}

ddir* ddirread(ddir* dp)
{
    struct dirent* ent=NULL;
    if(dp==NULL)
        return NULL;
    if(dp->_flag&_DDIR_ONDIR) {
        ent=readdir(dp->_dir);
        if(ent!=NULL) {
            if(dp->_catPos + strlen(ent->d_name) >= DDIR_PATHSIZE) {
                ent=NULL;
                errno=36;
            }
        } else { //end of directory
            dp->_flag=(dp->_flag&~_DDIR_SET)|_DDIR_EOF;
        }
        if(ent!=NULL) {
            strcpy(dp->_path + dp->_catPos,ent->d_name);
            dp->d_name=ent->d_name;
            dp->d_type= ddirtype(dp,ent);
            return dp;
        } else {
            dp->d_name=NULL;
            dp->d_type=0;
            dp->_path[dp->_catPos]=0;
        }
    }
    return NULL;
}

int ddirget(ddir* dp)
{
    void* p;
    char* s;
    p=ddirread(dp);
    if(p!=NULL) {
        if(dp->_flag&_DDIR_SET) {
            s= dp->_path + dp->_catPos;
            if(s[0]=='.'&&s[1]==0)
                p=ddirread(dp);
            if(s[0]=='.'&&s[1]=='.'&&s[2]==0)
                p=ddirread(dp);
            dp->_flag &=~_DDIR_SET;
        }
    }
    if(p!=NULL)
        return dp->d_type;
    else
        return 0;
}

int ddirclose(ddir* dp)
{
    if(dp==NULL)
        return -1;
    if(dp->_path!=NULL) {
        free(dp->_path);
        dp->_path=NULL;
    }
    if((dp->_flag&_DDIR_ONDIR)&&dp->_dir!=NULL)
        closedir(dp->_dir);
    dp->_dir=NULL;
    dp->_flag=0;
    free(dp);
    return 0;
}

int test_printdir(const char* path)
{
    int i,ftype;
    ddir *dp=ddiropen(path);
    if(dp==NULL) {
        printf("failed to opendir %s\n",path);
        return 0;
    }
    ftype=ddirget(dp);
    for(i=1;!deod(dp);++i) {
        switch(ftype) {
            case 4: printf("%d.directory:  %s\n%s\n\n",
                i,dp->d_name,dp->_path);
                break;
            case 8: printf("%d. file:    %s\n%s\n\n",
                i,dp->d_name,dp->_path);
                break;
            default: printf("%d.unknown(type:%d): %s\n%s\n\n",
                i,ftype,dp->d_name,dp->_path);
        }
        ftype=ddirget(dp);
    }
    return i-1;
}
int test_copydir(const char* path)
{
    int i,ftype;
    char namebuf[256]="/storage/emulated/0/sample/";
    int destCatPos=strlen(namebuf);
    ddir *dp=ddiropen(path);
    if(dp==NULL) {
        printf("failed to opendir %s\n",path);
        return 0;
    }
    ftype=ddirget(dp);
    for(i=1;!deod(dp);++i) {
        switch(ftype) {
            case 4: strcpy(namebuf + destCatPos,dp->_path + dp->_catPos);
                printf("%d.mkdir递归: %s\n",
                i,namebuf);
                break;
            case 8: strcpy(namebuf + destCatPos,dp->_path + dp->_catPos);
                printf("%d.copy file %s\nto %s\n",
                i,dp->_path,namebuf);
                break;
            default: printf("%d.unknown(type:%d): %s\n%s\n\n",
                i,ftype,dp->d_name,dp->_path);
        }
        ftype=ddirget(dp);
    }
    return i-1;
}

#endif

//终于完了

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/735306.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-27
下一篇 2022-04-27

发表评论

登录后才能评论

评论列表(0条)

保存