您的位置:首页 > 运维架构 > Linux

在linux下递归获取指定目录下指定扩展名的文件名列表

2010-12-07 11:22 531 查看
只用到了两个与目录相关的结果体:

#include <dirent.h>

struct __dirstream
{
void *__fd; /* `struct hurd_fd' pointer for descriptor. */
char *__data; /* Directory block. */
int __entry_data; /* Entry number `__data' corresponds to. */
char *__ptr; /* Current pointer into the block. */
int __entry_ptr; /* Entry number `__ptr' corresponds to. */
size_t __allocation; /* Space allocated for the block. */
size_t __size; /* Total valid data in the block. */
__libc_lock_define (, __lock) /* Mutex lock for this structure. */
};
typedef struct __dirstream DIR;

struct dirent
{
long d_ino; /* inode number 索引节点号 */
off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
unsigned short d_reclen; /* length of this d_name 文件名长 */
unsigned char d_type; /* the type of d_name 文件类型 */
char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
}

其中inode表示存放的是该文件的结点数目(具体可了解linux下的文件系统),d_off 是文件在目录中的编移,这两个基本很少用。
d_type表示档案类型:
enum
{
DT_UNKNOWN = 0,
# define DT_UNKNOWN DT_UNKNOWN
DT_FIFO = 1,
# define DT_FIFO DT_FIFO
DT_CHR = 2,
# define DT_CHR DT_CHR
DT_DIR = 4,
# define DT_DIR DT_DIR
DT_BLK = 6,
# define DT_BLK DT_BLK
DT_REG = 8,
# define DT_REG DT_REG
DT_LNK = 10,
# define DT_LNK DT_LNK
DT_SOCK = 12,
# define DT_SOCK DT_SOCK
DT_WHT = 14
# define DT_WHT DT_WHT
};

上实例程序:

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

/*文件信息:文件目录、文件名*/
struct FileInfo
{
char dir[512];
char filename[512];
}

/*
* 功能:
*		到指定目录,递归子目录的获取指定扩展名的文件,将文件信息(文件路径,名称),存储在一个表中,供后续工作使用
* 参数:
*		@sPath:  存储获取到文件名的路径
*		@sExtend: 文件扩展名
*		@*pFileList: 存储获取到文件名的vector对象的地址
*		@maxcount:获取文件信息数目的最大值
* 返回值:
*		>= 0: 获取文件信息的数目
*		-1:传入的目录或扩展名参数错误
*		-2:目录访问失败, 可能是传入的目录非法
*/
int get_filename_list(string sPath, string sExtend, vector<FileInfo> *pFileList, int maxcount)
{
if(sPath.size()< 1 || sExtend.size() <1)
return -1;

DIR*			pdir;
struct dirent*	pdir_ent;
string str_tmp;
string last_baking;
int dot_pos;

if(sExtend[0] != '.')
{
sExtend = '.' + sExtend;
}

if(sPath[sPath.size()-1] != '/') //目录都以"/"结尾
sPath += '/';

int getcount = 0;//获取到文件的个数
FileInfo myFileInfo;
pFileList->clear();

vector<string> vDirList;
string sCurDir;
vDirList.push_back(sPath);

string sSubDir;

while( !vDirList.empty() )
{
pdir_ent = NULL;
pdir = NULL;
sCurDir = vDirList.back();
vDirList.pop_back();

if((pdir = opendir(sCurDir.c_str())) == NULL)
{
printf("打开文件夹【%s】失败!", sCurDir.c_str());
return -2;
}

//printf("/n/n/n*********************** current is handling the [%s] directory *************************/n", sCurDir.c_str());
while((pdir_ent = readdir(pdir)) != NULL)
{
str_tmp.clear();
str_tmp = pdir_ent->d_name;

//printf("/n/t{---------- %s -----------------}/n",pdir_ent->d_name);

if(strcmp(pdir_ent->d_name, ".") == 0 || strcmp(pdir_ent->d_name, "..")==0 )
{
//printf("/t[%s --> omit it]/n", pdir_ent->d_name);
continue;
}

if(pdir_ent->d_type == DT_DIR)
{
sSubDir = sCurDir +  pdir_ent->d_name + "/";
vDirList.push_back( sSubDir );
//printf("/t#%s  as directory push_backed to vector#/n",pdir_ent->d_name);
continue;
}

if( (dot_pos = str_tmp.find_last_of(".")) == string::npos )
{
//printf("/t&111 %s  --->  not satisfy the extend&/n",pdir_ent->d_name);
continue;
}

if(str_tmp.substr(dot_pos,str_tmp.length() - dot_pos).compare(sExtend) !=0 )
{
//printf("/t&222 %s  --->  not satisfy the extend&/n",pdir_ent->d_name);
continue;
}

memset(&myFileInfo, 0, sizeof(struct FileInfo));

memcpy(myFileInfo.dir, sCurDir.c_str(), strlen(sCurDir.c_str()));
memcpy(myFileInfo.filename, str_tmp.c_str(), str_tmp.size());

pFileList->push_back(myFileInfo);

//printf("/t!%s  ---> OK!/n",pdir_ent->d_name);

getcount++;

if(getcount >= maxcount)
break;
}//while
closedir(pdir);
if(getcount >= maxcount)
break;
}//while

return(pFileList->size());
}

int cmpfunc(FileInfo a, FileInfo b)
{
string a_filepath = a.dir;
a_filepath += a.filename;
string b_filepath = b.dir;
b_filepath += b.filename;

return a_filepath < b_filepath;
}

int main(int argc, char** argv)
{
if(argc < 3 || strlen(argv[1]) < 1 || strlen(argv[2]) < 1)
{
printf("call error!/n Usages: dirOP path file_extend/n");
}

vector<FileInfo> myFilesList;
int file_list_max_count = 100;
int rtn = get_filename_list(argv[1], argv[2], &myFilesList, file_list_max_count);
if( rtn < 0)
{
printf("calling get_filename_list() occur error!/n");
}
else{
vector<FileInfo>::iterator iter;
for(iter=myFilesList.begin(); iter!=myFilesList.end(); ++iter)
{
printf("/n%s/t/t%s", iter->dir, iter->filename);
}

sort(myFilesList.begin(), myFilesList.end(), cmpfunc);

printf("/n/n/n/n after sorted data is:/n");
for(iter=myFilesList.begin(); iter!=myFilesList.end(); ++iter)
{
printf("/n%s/t/t%s", iter->dir, iter->filename);
}

printf("/n");
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: