139 votes

Obtenir une liste de fichiers dans un répertoire avec un glob.

Pour une raison inconnue, je n'arrive pas à trouver un moyen d'obtenir une liste de fichiers avec un glob pour un répertoire donné.

Je suis actuellement coincé avec quelque chose du genre :

NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSArray *dirContents = [[NSFileManager defaultManager] 
                        directoryContentsAtPath:bundleRoot];

puis en supprimant les éléments que je ne veux pas, ce qui est nul. Mais ce que j'aimerais vraiment, c'est pouvoir rechercher quelque chose comme "foo*.jpg" au lieu de demander tout le répertoire, mais je n'ai rien trouvé de tel.

Alors comment faire ?

0 votes

La réponse de Brian Webster m'a beaucoup aidé dans un problème similaire. stackoverflow.com/questions/5105250/

1 votes

Si vous lisez ceci, vous pouvez résoudre ce problème en plaçant vos fichiers dans un dossier. stackoverflow.com/questions/1762836/

242voto

Brian Webster Points 7516

Vous pouvez réaliser cela assez facilement avec l'aide de NSPredicate, comme ceci :

NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *dirContents = [fm contentsOfDirectoryAtPath:bundleRoot error:nil];
NSPredicate *fltr = [NSPredicate predicateWithFormat:@"self ENDSWITH '.jpg'"];
NSArray *onlyJPGs = [dirContents filteredArrayUsingPredicate:fltr];

Si vous devez le faire avec NSURL à la place, cela ressemble à ceci :

NSURL *bundleRoot = [[NSBundle mainBundle] bundleURL];
NSArray * dirContents = 
      [fm contentsOfDirectoryAtURL:bundleRoot
        includingPropertiesForKeys:@[] 
                           options:NSDirectoryEnumerationSkipsHiddenFiles
                             error:nil];
NSPredicate * fltr = [NSPredicate predicateWithFormat:@"pathExtension='jpg'"];
NSArray * onlyJPGs = [dirContents filteredArrayUsingPredicate:fltr];

2 votes

DirectoryContentsAtPath est déprécié depuis iOS 2.0. Cette question + réponse sont trop anciennes...

7 votes

Je viens de mettre à jour l'exemple de code pour utiliser contentsOfDirectoryAtPath:error : plutôt que directoryContentsAtPath :

0 votes

Cela a l'air génial ! Y a-t-il un moyen de formater le prédicat pour attraper deux types de fichiers à la fois, comme '.jpg' et '.png' ?

33voto

Matt Points 159

Cela fonctionne très bien pour IOS mais devrait également fonctionner pour cocoa .

NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSFileManager *manager = [NSFileManager defaultManager];
NSDirectoryEnumerator *direnum = [manager enumeratorAtPath:bundleRoot];
NSString *filename;

while ((filename = [direnum nextObject] )) {

    //change the suffix to what you are looking for
    if ([filename hasSuffix:@".data"]) {   

        // Do work here
        NSLog(@"Files in resource folder: %@", filename);            
    }       
}

28voto

John Biesnecker Points 2138

Et si vous utilisiez les méthodes hasSuffix et hasPrefix de NSString ? Quelque chose comme (si vous recherchez "foo*.jpg") :

NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSArray *dirContents = [[NSFileManager defaultManager] directoryContentsAtPath:bundleRoot];
for (NSString *tString in dirContents) {
    if ([tString hasPrefix:@"foo"] && [tString hasSuffix:@".jpg"]) {

        // do stuff

    }
}

Pour les correspondances simples et directes de ce type, il serait plus simple d'utiliser une bibliothèque regex.

0 votes

Vous devez utiliser contentsOfDirectoryAtPath:error: au lieu de directoryContentsAtPath parce que son deprecated desde iOS 2.0

0 votes

C'est la première réponse de la liste à répondre à la question, j'ai donc voté pour elle.

12voto

SVMRAJESH Points 1685

Méthode très simple :

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
                                                     NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];

NSFileManager *manager = [NSFileManager defaultManager];
NSArray *fileList = [manager contentsOfDirectoryAtPath:documentsDirectory 
                                                 error:nil];
//--- Listing file by name sort
NSLog(@"\n File list %@",fileList);

//---- Sorting files by extension    
NSArray *filePathsArray = 
  [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory  
                                                      error:nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF EndsWith '.png'"];
filePathsArray =  [filePathsArray filteredArrayUsingPredicate:predicate];
NSLog(@"\n\n Sorted files by extension %@",filePathsArray);

10voto

Bryan Kyle Points 5931

Unix possède une bibliothèque qui peut effectuer des opérations de globbing de fichiers pour vous. Les fonctions et les types sont déclarés dans un en-tête appelé glob.h Vous devrez donc #include il. Si vous ouvrez un terminal et ouvrez la page de manuel pour glob en tapant man 3 glob vous obtiendrez toutes les informations dont vous avez besoin pour utiliser les fonctions.

Voici un exemple de la façon dont vous pouvez remplir un tableau avec les fichiers qui correspondent à un modèle de globbing. Lorsque vous utilisez la méthode glob fonction, il y a quelques éléments que vous devez garder à l'esprit.

  1. Par défaut, le glob recherche les fichiers dans le répertoire de travail actuel. Afin de rechercher dans un autre répertoire, vous devrez ajouter le nom du répertoire au motif de globbing, comme je l'ai fait dans mon exemple pour obtenir tous les fichiers de /bin .
  2. Vous êtes responsable du nettoyage de la mémoire allouée par le programme glob en appelant globfree quand vous aurez fini avec la structure.

Dans mon exemple, j'utilise les options par défaut et aucun rappel d'erreur. La page de manuel couvre toutes les options au cas où vous voudriez utiliser quelque chose. Si vous utilisez le code ci-dessus, je vous suggère de l'ajouter en tant que catégorie dans le fichier NSArray ou quelque chose comme ça.

NSMutableArray* files = [NSMutableArray array];
glob_t gt;
char* pattern = "/bin/*";
if (glob(pattern, 0, NULL, &gt) == 0) {
    int i;
    for (i=0; i<gt.gl_matchc; i++) {
        [files addObject: [NSString stringWithCString: gt.gl_pathv[i]]];
    }
}
globfree(&gt);
return [NSArray arrayWithArray: files];

Edit : J'ai créé un gist sur github qui contient le code ci-dessus dans une catégorie appelée NSArray+Globbing .

0 votes

stringWithCString: est déprécié. Le remplacement correct est -[NSFileManager stringWithFileSystemRepresentation:length:] bien que je pense que la plupart des gens utilisent stringWithUTF8String: (ce qui est plus facile mais pas garanti d'être le bon encodage).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X