[Résolu] Compter les fichiers d'un répertoire

berfisberfis Membre
mai 2013 modifié dans API AppKit #1

Bonsoir,


 


Voilà  plusieurs jours que je suis aux prises avec le FileManager, que j'utilise les enumeratorAtPath, contentsOfDirectoryAtPath et autres attributesOfItemAtPath, sans compter les jonglages entre NSURL et NSString, j'en passe et des pires, tout ça pour ne pas parvenir au résultat voulu:


 


Dans une hiérarchie de répertoires et de documents, je veux obtenir la liste des répertoires qui contiennent uniquement des documents (donc en fait le dernier niveau de la hiérarchie). Sont exclus les répertoires vides ou les répertoires qui contiennent d'autres répertoires.


 


Existe-t-il un moyen simple de faire cela, en démarrant de la liste d'un répertoire (par exemple le dossier Documents)? Peut-on trier à  l'aide de prédicats, si oui lesquels? Comment zapper les fichiers .DS_Store?


 


Croyez bien que j'ai lutté avant de poser la question. Je dois mal m'y prendre... ou alors c'est vraiment compliqué?


 


Merci d'avance.


Réponses

  • laudemalaudema Membre
    avril 2013 modifié #2

    As tu essayé avec ça, qui permet d'exclure fichiers cachés et | ou sous-répertoires et qu'est ce qui n'a pas fonctionné ?


    Sinon, dans les moyens "simples" tu as aussi une méthode (relativement) méconnue de NSString :



    completePathIntoString:caseSensitive:matchesIntoArray:filterTypes:

    Interprets the receiver as a path in the file system and attempts to perform filename completion, returning a numeric value that indicates whether a match was possible, and by reference the longest path that matches the receiver.


    - (NSUInteger)completePathIntoString:(NSString **)outputName caseSensitive:(BOOL)flag matchesIntoArray:(NSArray **)outputArray filterTypes:(NSArray *)filterTypes

    Si tous tes fichiers ont un préfixe commun ..


  • Tout est faisable. Essaye le petit logiciel joint, même si ce n'est pas exactement ce que tu cherches.


  • berfisberfis Membre
    avril 2013 modifié #4

    Bonjour laudema,


     


    Le moins que l'on puisse dire, à  voir les occurrences sur la toile, c'est que le système de fichiers n'est pas évident à  comprendre. Si je travaillais par glisser-déposer, je me simplifierais sans doute la vie, mais je travaille par... sélection dans le finder (je ne te raconte pas pour la récupérer via SBElementArray)...


     


    Le gros piège que je me suis tendu à  moi-même, et dans lequel je suis naturellement tombé, est d'utiliser 



    changeCurrentDirectoryPath:

     


    pour "simplifier" la construction des chemins d'accès. Bad, bad idea indeed. Du coup, pour copier un fichier d'un répertoire à  l'autre, je ne savais plus où j'en étais... J'en suis donc revenu à  des paths/url/NSURL/NSString (...) reconstruits entièrement. Ca donne des lignes de code trèèès longues, je déteste ça.


     


    J'en suis à  dériver NSObject pour créer des énumérateurs et isoler ce qui ne marche pas. Dernier essai:



    @implementation FileEnumerator
    - (FileEnumerator*) initWithPath: (NSString*)aPath {
    self = [super init];
    NSFileManager *fm = [NSFileManager defaultManager];
    self.numItems = 0;
    NSArray * contents = [fm contentsOfDirectoryAtPath:aPath error:nil];
    for (NSString *subPath in contents) {
    NSDictionary *fileDic =[fm attributesOfItemAtPath:subPath error:nil];
    if (![fileDic objectForKey:@NSFileType]) self.numItems++;
    }
    return self;
    }
    @end

     


    Faire un test du genre if (![fileDic objectForKey:@NSFileType]) est vraiment minable, d'autant plus que ces fichus .DS_Store passent entre les gouttes, compliquant le dénombrement.


     


    @tablier : sans le source, je ne vois pas ce que cherche à  faire "Répertoire"...


  • Ben justement, en plus tu veux retourner un enumerator donc j'utiliserais les méthodes éponymes de NSFileManager enumeratorAtPath ou enumeratorAtURL qui retournent un enumerator et dont les options NSDirectoryEnumeration-skipSubdirectoryDescendants - SkipsPackageDescendant -SkipsHiddenFiles permettent d'éviter les sous répertoires les packages et les fichiers cachés (type .DS_Store)...

  • Pour revenir sur le méconnu completePathIntoString: 



    NSString *aPStr = [@~/Documents/ stringByStandardizingPath];
    NSString *oStr;
    NSArray *aAr;
    NSUInteger dotCount = 0;
    NSUInteger result = [aPStr completePathIntoString:(NSString **)&oStr caseSensitive:(BOOL)NO matchesIntoArray:&aAr filterTypes:nil];
    printf("%ld chemins. ", (unsigned long)result);
    for (NSString *path in aAr){
    char c = [[path lastPathComponent] characterAtIndex:0];
    if ('.' == c) {
    dotCount ++;
    continue;
    }
    NSDictionary *attribs = [[NSFileManager defaultManager] attributesOfFileSystemForPath:path error:NULL];
    if ([[attribs objectForKey:NSFileType]isEqualToString:NSFileTypeDirectory]) {
    result --;
    }
    }
    printf("%ld n'étaient pas des répertoires et %ld étaient des fichiers cachés\n", result, dotCount);


    /*475 chemins. 475 n'étaient pas des répertoires et 2 étaient des fichiers cachés*/



     

     


  • les options NSDirectoryEnumeration-skipSubdirectoryDescendants - SkipsPackageDescendant -SkipsHiddenFiles permettent d'éviter les sous répertoires les packages et les fichiers cachés (type .DS_Store)...


    Eh bien, je n'avais pas planché assez. Je faisais du myEnumerator.AllObjects et je filtrais moi-même après. Bien utile pour les .count, en effet.


     


    Merci!

Connectez-vous ou Inscrivez-vous pour répondre.