一.目录操作库函数opendir/readdir/closedir
使用头文件<dirent.h>
1.opendir —打开一个目录流
DIR* dp = opendir(“文件名”)
DIR是操作系统提供的一个结构体,opendir函数返回一个DIR*,其指向一个目录流。
2.readdir —对目录进行读取,每次读取其中一个文件,在到达目录流末尾时,返回NULL
dirent* sdp = readdir(DIR*)
通过传入DIR*,对一个目录进行读取,每次返回一个dirent*,指向一个文件。dirent是一个结构体,包含该文件的inode和name属性等
如下,一个dirent结构体内部实现。
3.closedir—关闭一个目录流
close(DIR*)
传入一个DIR*,对其关闭,失败返回-1,成功返回0
二.实现递归遍历目录
思路:传入一个目录,将其opendir打开获取DIR*,通过readdir依次获取内部文件,对于每一个文件,通过stat函数获取文件信息,检查其stat结构体中的st_mode属性,如果是文件,直接打印输出,如果是目录,则将该目录名作为参数,递归执行遍历函数。
需要注意的是,文件需要使用绝对路径,因为工作目录固定,在对其它目录操作时,相对路径找不到指定文件,所以在递归之前,需要拼接文件路径。
#include<iostream>
#include<unistd.h>
#include<dirent.h>
#include<sys/stat.h>
using namespace std;
bool IsFile(char*Name,int&size);
void ReadDir(char* Name) //遍历目录函数
{
int size;
char path[256];
DIR* dp;
struct dirent* sdp;
dp = opendir(Name);
if(dp==NULL)
{
perror("error");
return ;
}
while((sdp=readdir(dp))!=NULL)
{
sprintf(path,"%s/%s",Name,sdp->d_name);
if( (sdp->d_name)[0] == '.' )
{
continue;
}
if(IsFile(path,size))
{
cout<<sdp->d_name<<" "<<size<<endl;
}
else
{
ReadDir(path);
}
}
closedir(dp);
return ;
}
bool IsFile(char* Name,int &size)//使用stat,传入文件名判断是否为目录
{
int flag;
struct stat sb;
flag = stat(Name,&sb);
size = sb.st_size;
if(!S_ISDIR(sb.st_mode))
{
return true;
}
else
{
return false;
}
}
int main(int argc,char* argv[])
{
ReadDir(argv[1]);
return 0;
}