FindFile C++/Linux

Das ist ein kurzer Basiscode um schnell einen Verzeichnisbaum zu durchlaufen. Kann als Basis dienen für andere Anwendungen wie:

  • Wo ist die Datei?
  • Wohin ist mein Plattenplatz verschwunden?
  • usw

Für Windows müssten nur die Funktionen readdir und opendir in FindFirstFile und FindNextFile umgebaut werden.

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>

#include <string>
#include <set>

#define MAXPATHLEN  1024

#define LEFT 1

typedef std::set< std::string, std::less< std::string > > stringset_t;

bool isfile(const struct stat &);
bool isdir(const struct stat &);
bool isroot(const char *);


int read_dir(stringset_t & vNameList, char *name);

void checkifisdir(const char *szDirName)
{
    struct stat sb;
    if(stat(szDirName, &sb) < 0)
    {
        perror(szDirName);
        exit(1);
    }
    if(!isdir(sb))
    {
        fprintf(stderr, "%s ist kein Verzeichnis\n", szDirName);
        exit(1);
    }
}

int read_dir(const char *szBaseName, char *szFileName, stringset_t & vNameList)
{
    std::string strFullPath = szBaseName;

    if(szFileName != 0)
        strFullPath += std::string("/")  + szFileName;

    DIR * dirp;
    struct dirent *d;

    dirp = opendir(strFullPath.c_str());
    if(dirp == NULL)
        return 0;

    while( d = readdir(dirp))
    {
        char szPath[MAXPATHLEN];
        sprintf(szPath, "%s/%s", strFullPath.c_str(), d->d_name);
        struct stat sb;
        if(stat(szPath, &sb) < 0)
        {
            continue;
        }

        if(isdir(sb))
        {
            if((strcmp(".", d->d_name) == 0) || (strcmp("..", d->d_name) == 0))
            {
                continue;
            }
            if(szFileName != 0)
                sprintf(szPath, "%s/%s", szFileName, d->d_name);
            else
                strcpy(szPath, d->d_name);

            read_dir(szBaseName, szPath, vNameList);
        }

        if(isfile(sb))
        {
            if(szFileName != 0)
                sprintf(szPath, "%s/%s", szFileName, d->d_name);
            else
                strcpy(szPath, d->d_name);

            vNameList.insert(szPath);
        }
    }

    closedir(dirp);
}

bool isfile(const struct stat & sb)
{
    return S_ISREG(sb.st_mode);
}

bool isdir(const struct stat & sb)
{
    return S_ISDIR(sb.st_mode);
}

bool isroot(char *szDir)
{
    struct stat root;
    struct stat directory;

    int i = stat("/", &root);
    if(i < 0)
    {
        perror("stat fehlgeschlagen");
        exit(1);
    }

    int j = stat(szDir, &directory);
    if(j < 0)
    {
        char szMessage[1000];
        sprintf(szMessage, "stat fehlgeschlagen (%s)", szDir);
        perror(szMessage);
        exit(1);
    }

    if(root.st_ino == directory.st_ino)
        return true;

    return false;
}

Kann mit dem Standard-Makefile übersetzt werden.