#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <vector>
using namespace std;
enum ElementType { SIMPLEFILE, DIRECTORY, SYMBOLICLINK };
class Element{
public:
Element(){};
Element(char *name_, char *full_path_name_, ElementType element_type_, long element_size_)
: name(NULL), full_path_name(NULL), element_size(0)
{
memcpy (name,name_,strlen(name_)+1);
memcpy (full_path_name,full_path_name_,strlen(full_path_name_)+1);
element_type=element_type_;
element_size=element_size_;
};
char *name;
char *full_path_name;
ElementType element_type;
long element_size;
};
int inspect(const char *input_path, std::vector<Element>& result_element_array, long *dir_size,const char *full_path ) {
std::vector<Element> result_element_array_temp;
DIR *d;
struct dirent *dir;
struct stat buf;
char *mynamebuf=(char *)malloc(0);
int c=0;
size_t base_len = strlen(full_path);
long dir_size_temp=0;
char *full_path_temp=(char *)malloc(0);
char *full_path_dummy=(char *)malloc(0);
result_element_array_temp.reserve(1000);
d = opendir( full_path);
if( d == NULL ) {
return 1;
}
while( ( dir = readdir( d ) )) {
if( strcmp( dir->d_name, "." ) == 0 || strcmp( dir->d_name, ".." ) == 0 ) {
continue;
}
memcpy (mynamebuf,full_path,strlen(full_path)+1);
strcat(mynamebuf,(full_path[base_len - 1] == '/' ? "" : "/"));
strcat(mynamebuf,dir->d_name);
if (stat(mynamebuf, &buf) != 0) {
perror(mynamebuf);
continue;
}
if( S_ISDIR(buf.st_mode) ) {//if dir
chdir( dir->d_name );
memcpy (full_path_temp,full_path,strlen(full_path)+1);
strcat(full_path_temp,"/");
strcat(full_path_temp,dir->d_name);
(dir_size_temp)=0;
inspect( ".", result_element_array_temp, &dir_size_temp, full_path_temp );
chdir( ".." );
memcpy (full_path_dummy,full_path_temp,strlen(full_path_temp)+1);
strcat(full_path_dummy,"/");
strcat(full_path_dummy,dir->d_name);
Element element;
element.name=dir->d_name;
element.full_path_name=full_path_dummy;
element.element_type=DIRECTORY;
element.element_size=dir_size_temp;
result_element_array.push_back(element);
result_element_array.insert( result_element_array.end(), result_element_array_temp.begin(), result_element_array_temp.end() );
(*dir_size)+=(dir_size_temp);
} else if( S_ISREG(buf.st_mode)) {//if file
memcpy (full_path_dummy,full_path,strlen(full_path)+1);
strcat(full_path_dummy,"/");
strcat(full_path_dummy,dir->d_name);
Element element;
element.name=dir->d_name;
element.full_path_name=full_path_dummy;
element.element_type=SIMPLEFILE;
element.element_size=buf.st_size;
result_element_array.push_back(element);
(*dir_size)+=buf.st_size;
} else if( S_ISLNK(buf.st_mode) ) {//if link
memcpy (full_path_dummy,full_path,strlen(full_path)+1);
strcat(full_path_dummy,"/");
strcat(full_path_dummy,dir->d_name);
Element element;
element.name=dir->d_name;
element.full_path_name=full_path_dummy;
element.element_type=SIMPLEFILE;
element.element_size=buf.st_size;
result_element_array.push_back(element);
} else {
continue;
}
}
closedir(d);
return 0;
}
int main(){
std::vector<Element> result_element_array;
result_element_array.reserve(3000);
long dir_size;
const char *full_path="/";
inspect("/", result_element_array, &dir_size,full_path );
std::vector <Element>::iterator It;
for(It = result_element_array.begin(); It != result_element_array.end(); ++It){
printf("%s\n",(*It).full_path_name);
}
return 0;
}
代码在上面。我的目标是递归地编写目录浏览器。
我对代码进行了 GDB,它在递归调用方法return 0
时到达,但无法执行。可能与其他一些行引起的stackoverflow有关吗?任何想法将不胜感激。inspect
return 0