2009-05-22 6 views
0

Je cherche à écrire un scanner de système de fichiers portable, capable de répertorier récursivement tous les fichiers sur un chemin de répertoire donné.C++ Analyse récursive de fichiers/répertoires en utilisant Cygwin

Pour ce faire, je tente d'utiliser Cygwin pour mon compilateur, en utilisant dirent.h et en utilisant le modèle:

#include <dirent.h> 
#include <stdio.h> 

int main(void) 
{ 
    DIR   *d; 
    struct dirent *dir; 
    d = opendir("."); 
    if (d) 
    { 
    while ((dir = readdir(d)) != NULL) 
    { 
     // Stuff 
    }  
    closedir(d); 
    }  
    return(0); 
} 

Mais besoin d'ajouter récursive recherche aussi bien. Pour ce faire, ma solution consistait à essayer opendir() sur le fichier suivant, et à juger le code d'erreur pour déterminer s'il avait été ouvert avec succès en tant que répertoire (sur lequel je me récurserais) ou s'il était retourné un répertoire ', qui serait alors répertorié comme un simple fichier. J'avoue que cela semble très difficile, mais j'ai été incapable de trouver une meilleure méthode qui peut conserver une certaine portabilité (pas win32), même après des heures de recherche.

donc ma solution simplifiée (certains psuedo pour simplifier) ​​est à la recherche quelque chose comme ceci:

 
int scan(string startdir) 
{ 
    DIR   *d; 
    struct dirent *dir; 
    d = opendir(startdir.cstr()); 
    if (d) 
    { 
    while ((dir = readdir(d)) != NULL) 
    { 
     if(NOT '.' AND NOT '..') 
     { 
     if(temp = opendir(startdir + d) == NULL) 
     { 
      //FILE OR ERROR 
     }else{ 
      //Opened successfully as a directory, so recurse 
      scan(startdir + d->d_name + "\\"); 
     } 
     } 
    } 
    closedir(d); 
    } 
    return(0); 
} 

Ceci est juste la moitié réécrite code psuedo pour le garder simple, mais il semble fonctionner (même si je suis très ouvert aux suggestions sur les meilleures façons de le faire). Le problème majeur que j'ai, cependant, est un fichier de lien particulier 'c: \ cygwin \ dev \ fd' qui semble s'ouvrir comme un répertoire et s'ouvrir récursivement indéfiniment. Le fichier 'fd' est de 4 Ko, 106 octets sans extension et est un raccourci qui ne pointe nulle part dans Windows.

Cette erreur semble indiquer que soit cette méthode kludgey est mis sur écoute, ou il y a un problème dans la mise en œuvre de Cygwin que je compiler dans

En bref exemple:.

Error Reading: c:\cygwin\dev\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\5\fd\0 No such file or directory

À l'exclusion de répertoire, la recherche semble bien fonctionner. Mais je ne suis pas d'accord avec le codage dur d'une exclusion dans le scanner.

Si quelqu'un a des idées, des suggestions, des solutions ou des méthodes alternatives à ce problème, votre contribution serait appréciée.

Merci.

Répondre

1

Le coupable semble être que les liens de fichier fd dans/proc/

Je ne garantissons pas que ce soit vrai, mais je suis sous l'impression que cela permet au scanner de boucle récursive dans sa propre structure de répertoire .Mes efforts avec readlink() pour résoudre ce problème étaient prometteurs au début, mais je constate qu'avec des niveaux d'analyse plus profonds, il devient peu fiable et les erreurs peuvent toujours se produire.

Je suis maintenant à la recherche d'autres moyens d'atteindre cette fonctionnalité (par exemple boost :: filesystem).

0

C'est un système de fichiers virtuel, peut-être avec des liens symboliques. Cygwin prend en charge les liens symboliques, et vous devrez peut-être prendre en compte ce facteur.

1

Si vous pouvez utiliser boost, pensez à utiliser boost::filesystem. Les tutoriels incluent un programme ls simple que vous pouvez facilement étendre pour travailler récursivement. La bibliothèque comprend également des méthodes pour interroger les types de fichiers, ce qui peut probablement résoudre votre problème spécifique.

+0

Bien que ce soit probablement une bonne idée, je suis hésitant à utiliser d'autres bibliothèques (même gratuites) qui nécessitent d'autres discussions et l'approbation des plus hauts. Je vais regarder plus loin (comme je l'ai vu mentionné ailleurs aussi bien) et éventuellement faire le pitch. Merci pour les commentaires – KevenK

0

Vous réalisez que cygwin possède tous les outils UNIX.

La recherche est très utile.

0

La bibliothèque cygwin possède à la fois ftw() et fts(), utilisez l'un de ceux-ci.

0

Dans votre exemple, vous avez essayé à nouveau d'utiliser opendir() pour déterminer si quelque chose est un fichier ou un répertoire. Vous pouvez le faire plus directement en utilisant stat() depuis "sys/stat.h". Cela devrait également être disponible dans cygwin. Vous pouvez utiliser les macros S_ISREG() et S_ISDIR() pour rechercher un fichier ou un répertoire standard. Probablement quelque chose comme ceci:

struct stat *buf = new struct stat; 
    if(!stat(d->d_name, buf)) 
    { 
     if(S_ISREG(buf->st_mode)) 
     { 
      std::cout << " File: " << entry->d_name << "\n"; 
     } 
     if(S_ISDIR(buf->st_mode) && 

S'il vous plaît ont également un coup d'oeil au answer j'ai fourni à l'autre question.

Questions connexes