Unterverzeichnis durchsuchen



  • HANDLE fHandle;
    WIN32_FIND_DATA wfd;

    fHandle=FindFirstFile("c:\\windows\\desktop\*",&wfd);

    FindNextFile(fHandle,&wfd);

    while
    

    (FindNextFile(fHandle,&wfd))
    {
    if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    {
    // Hier will ich das Verzeichnis durchsuchen
    }
    else
    {
    MessageBox(0,wfd.cFileName,"Folgende Datei gefunden:",0);
    }
    }
    FindClose(fHandle);

    soweit die Faq.
    Wie bekomm ich den Pfad des Verzeichnisses raus, sodass ich wieder

    FindFirstFile()

    einsetzen kann, oder gibts da n trick ? 😕



  • Also ich hab sowas nur mal unter DOS in Assembler programmiert und kann dir somit keinen Code geben. Allerdings müsste das im Prinzip genauso gehen. Erstelle am besten eine Funktion wie:

    void blah(HANDLE findhandle);
    

    Die sollte dann nach Verzeichnissen suchen und wenn sie eins findet, dann wechselt sie in dieses Verzeichnis und ruft sich selbst wieder auf (Rekursion). Am besten schreibst du dann noch eine benutzerfreundlichere Funktion dazu, in etwa:

    void blah2(char *startdirectory);
    

    Diese Funktion sollte dann das aktuelle Verzeichnis speichern, ins Verzeichnis wechseln wo die Suche begonnen werden soll wechseln, die andere Funktion aufrufen und schließlich wieder ins alte Verzeichnis wechseln.

    Ich hoffe das hilft dir.



  • nein, das hilft mir leider nicht, da ich das ja so in etwa machen will, aber nicht weiß wie ich den pfad rauskriegen soll!! 😞



  • Mach es wie malfunction vorgeschlagen hat, mit

    void blah2(char *startdirectory);
    

    Der von Dir gesuchte Verzeichnisname steht in

    wfd.cFileName
    

    diesen Namen hängst Du mit einem \ an das startdirectiory. Dann gehst Du in die Rekursion. blah2 ruft dann für Dich wieder FindFirstFile() auf.



  • Vielleicht hilft dir auch das hier



  • habs nun mit Rekursion gemacht, schaut euch mal den code an und sagt mir, was ihr davon haltet. Verbraucht der nicht zuviel Speicher??

    #define STRICT
    
    #include <windows.h>
    #include <stdio.h>
    
    const char StartPath[] = "c:\\";
    
    bool GetDataPos (char *, char *);
    
    int WINAPI WinMain (HINSTANCE hInstance,
                        HINSTANCE hPrevInstance,
                        PSTR      szCmdLine,
                        int       iCmdShow)
    {
        HANDLE fHandle;
        WIN32_FIND_DATA wfd;
        char * Path = new char[250];
        char * nextPath = new char[250];
    
        sprintf (Path, "%s*", StartPath);
        sprintf (nextPath, "%s", StartPath);
    
        fHandle = FindFirstFile (Path,&wfd);
    
        FindNextFile (fHandle, &wfd);
    
        while (FindNextFile (fHandle, &wfd))
        {
            if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                MessageBox(0, wfd.cFileName, "Verzeichnis:", MB_OK);
                sprintf(nextPath, "%s\\%s\\", nextPath, wfd.cFileName);
    
                GetDataPos (Path, nextPath);
            }
            else
            {
                MessageBox(0, wfd.cFileName, "Datei:", MB_OK);
            }
        }
    
        delete [] Path;
        delete [] nextPath;
        FindClose(fHandle);
    
        return 0;
    
    }
    
    bool GetDataPos (char * Path, char * nextPath)
    {
        HANDLE fHandle;
        WIN32_FIND_DATA wfd;
    
        sprintf (Path, "%s*", nextPath);
    
        fHandle = FindFirstFile (Path,&wfd);
    
        FindNextFile (fHandle, &wfd);
    
        while (FindNextFile (fHandle, &wfd))
        {
            if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                MessageBox(0, wfd.cFileName, "Verzeichnis:", MB_OK);
                sprintf(nextPath, "%s\\%s\\", nextPath, wfd.cFileName);
    
                GetDataPos (Path, nextPath);
            }
            else
            {
                MessageBox(0, wfd.cFileName, "Datei:", MB_OK);
            }
        }
    
        FindClose(fHandle);
    
        return true;
    }
    

    [ Dieser Beitrag wurde am 06.04.2003 um 11:28 Uhr von flenders editiert. ]



  • Benutz doch endlich mal die CODE-TAGS!

    beim posten, ganz unten rechts neben den Smilies, der blaue [C++ Code] Button....

    Mann mann mann...



  • Vielen Danke an flenders für die nachträglich eingefügten [code]-Tags.

    @N00Bie:
    Du hast 2 Fehler drin.
    1. Ich habe dein Programm gerade mal ausprobiert, da ich der Meinung war, daß es eigentlich gar nicht funktionieren kann. Es sollte sich in einer Endlosschleife verfangen und mit einem Stack-Overflow abstürzen, weil Du die Spezialverzeichnisse . =das aktuelle Verzeichnis und .. =das darüberliegende Verzeichnis nicht berücksichtigst.

    2. Dass das Programm dennoch zu einem Ende kommt, liegt an einem anderen Fehler. Du benutzt den Speicherplatz von Path in jeder Rekursionsstufe. GetDataPos() bekommt die Adresse und benutzt dadurch den Speicherbereich von WinMain's Path. GetDataPos() selbst legt keinen eigenen Speicherbereich für den Pfad an. Deshalb werden nicht alle Verzeichnisse durchsucht. Zum Glück werden auch die besagten Punktverzeichnisse nicht gefunden.

    Wenn Du die gefundenen Dateien sofort verarbeitest (z.B. anzeigen, löschen, kopieren, auslesen...) brauchst Du keinen dynamischen Speicher.

    Meine Lösung sieht so aus:
    [cpp]

    #include <windows.h>
    #include <stdio.h>

    int ShowFiles(LPTSTR szDir)
    {
    WIN32_FIND_DATA wfd;
    HANDLE hff;
    int nFiles = 0;
    TCHAR szFilename[MAX_PATH];

    wsprintf(szFilename, TEXT("%s\*.*"), szDir);
    hff = FindFirstFile(szFilename, &wfd);
    if (hff == INVALID_HANDLE_VALUE)
    return -1;

    do {
    wsprintf(szFilename, TEXT("%s\%s"), szDir, wfd.cFileName);
    if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
    if ((strcmp(wfd.cFileName, ".") != 0) && (strcmp(wfd.cFileName, "..") != 0)) {
    printf("Durchsuche Unterverzeichnis %s...\n", szFilename);
    nFiles += ShowFiles(szFilename);
    printf("... fertig mit Unterverzeichnis %s\n", szFilename);
    }
    }
    else {

    printf("Datei: %s\n", szFilename);
    nFiles++;
    }
    } while (FindNextFile(hff, &wfd));

    FindClose(hff);
    return nFiles;
    }

    int main(void)
    {
    char *szStartDir = "C:\\temp";

    printf("%d Dateien in %s\n", ShowFiles(szStartDir), szStartDir);

    return 0;
    }[/code]

    [ Dieser Beitrag wurde am 06.04.2003 um 12:53 Uhr von John editiert. ]



  • zu 1. Die Verzeichnisse werden beim Suchen einfach übergangen.
    Der Aufruf von FindFirstFile() gibt das . -Verzeichnis zurück,
    das nächste FindNextFile() das .. -Verzeichnis. danach wird mit der
    Suche fortgefahren.

    zu 2. Path ist nur zum Finden von Dateien da. Er wird bei jedem Aufruf neu aus
    nextPath und wfd.cFileName generiert. Ich habe in diesem Fall Zeiger
    benutzt, da sonst bei jedem Aufruf von GetDataPos ein neues Array im Stack
    erzeugt würde, und bis zum endgültigen Ende nicht wieder gelöscht würde.
    So gibt es Path und nextPath nur einmal, und nicht so oft, wie es Ordner
    gibt (wie bei dir).

    meinung ??



  • So, ich hab das mal programmiert. Soweit ich es getestet hab funktioniert es ganz gut. Du kannst den Code, der für jedes Verzeichnis ausgeführt werden soll, an der kommentierten Stelle einfügen (am besten einen Funktionsaufruf, der Übersicht halber). Beschwert euch nicht, wenn der Code in irgendeiner Form ineffizient oder unelegant sein sollte. Ich programmiere vorwiegend in Assembler und nicht in C. Aufgerufen werden sollte die Funktion DirectoryTraversal, der der Startpfad übergeben werden soll. Vielleicht ist dieser Code ja auch was für die FAQ, wenn da nicht bereits was ähnliches stehen sollte. Genug der Worte, lasst Code sprechen:

    /* directory traversal written by Malfunction */
    
    void RecurseDirectories(void)
    {
        static WIN32_FIND_DATA findData;
        HANDLE findHandle;
    
        /* insert your code in here */
    
        findHandle=FindFirstFile("*.*",&findData);
    
        while(findHandle!=INVALID_HANDLE_VALUE)
        {
            if(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                if(strcmp(".",(char *)&findData.cFileName) &&
                   strcmp("..",(char *)&findData.cFileName))
                {
                    SetCurrentDirectory((char *)&findData.cFileName);
                    RecurseDirectories();
                    SetCurrentDirectory("..");
                }
            }
            if(!FindNextFile(findHandle,&findData)) break;
        }
        FindClose(findHandle);
        return;
    }
    
    void DirectoryTraversal(const char *startDir)
    {
        char CurrentDir[MAX_PATH];
    
        GetCurrentDirectory(MAX_PATH,(char *)&CurrentDir);
        SetCurrentDirectory(startDir);
        RecurseDirectories();
        SetCurrentDirectory((char *)&CurrentDir);
        return;
    }
    

Anmelden zum Antworten