C语言,C++的文件夹 *** 作常见的只有opendir(),readdir(),closedir(),rewinddir(),在
每次使用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
#include
#include
//windows: #include
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
//终于完了
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)