Pour une raison folle, je ne trouve pas le 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];
..et puis dépouillant ce que je ne veux pas, ce qui est nul. Mais ce que j'aimerais vraiment, c'est pouvoir chercher quelque chose comme "foo * .jpg" au lieu de demander tout le répertoire, mais je n'ai rien trouvé de tel.
Alors comment diable le faites-vous?
Vous pouvez y arriver assez facilement avec 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 avez besoin de 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];
Cela fonctionne assez bien pour IOS
, mais devrait aussi 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);
}
}
Qu'en est-il des 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 des correspondances simples et simples comme celle-ci, il serait plus simple d'utiliser une bibliothèque de regex.
Méthode la plus 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);
Unix a une bibliothèque qui peut effectuer des opérations de vidage de fichiers pour vous. Les fonctions et les types sont déclarés dans un en-tête appelé glob.h
, vous aurez donc besoin de #include
il. Si vous ouvrez un terminal, ouvrez la page de manuel de glob en tapant man 3 glob
vous obtiendrez toutes les informations nécessaires pour utiliser les fonctions.
Vous trouverez ci-dessous un exemple de la manière dont vous pourriez remplir un tableau avec les fichiers correspondant à un modèle de remplacement. Lorsque vous utilisez la fonction glob
, vous devez garder à l’esprit quelques points.
glob
recherche les fichiers du répertoire de travail en cours. Afin de rechercher un autre répertoire, vous devez ajouter le nom du répertoire au motif de remplacement tel que je l’ai fait dans mon exemple pour obtenir tous les fichiers au format /bin
.glob
en appelant globfree
lorsque vous avez terminé 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 souhaiteriez utiliser quelque chose. Si vous envisagez d'utiliser le code ci-dessus, je suggérerais de l'ajouter en tant que catégorie à NSArray
ou quelque chose du genre.
NSMutableArray* files = [NSMutableArray array];
glob_t gt;
char* pattern = "/bin/*";
if (glob(pattern, 0, NULL, >) == 0) {
int i;
for (i=0; i<gt.gl_matchc; i++) {
[files addObject: [NSString stringWithCString: gt.gl_pathv[i]]];
}
}
globfree(>);
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 .
Vous devez utiliser votre propre méthode pour éliminer les fichiers que vous ne voulez pas.
Ce n'est pas facile avec les outils intégrés, mais vous pouvez utiliser RegExKit Lite pour vous aider à trouver les éléments dans le tableau retourné qui vous intéresse. Selon les notes de publication, cela devrait fonctionner à la fois dans Cocoa et les applications Cocoa-Touch.
Voici le code de démonstration que j'ai rédigé en 10 minutes environ. J'ai changé le <et> en "parce qu'ils n'apparaissaient pas à l'intérieur du bloc pré, mais cela fonctionne toujours avec les guillemets. Peut-être que quelqu'un qui en sait plus sur le code de formatage ici sur StackOverflow corrigera cela (Chris?).
Il s'agit d'un projet de modèle d'utilitaire de ligne de commande "Foundation Tool". Si mon démon git est opérationnel sur mon serveur domestique, je modifierai ce message pour ajouter l'URL du projet.
# import "Foundation/Foundation.h" # import "RegexKit/RegexKit.h" @ interface MTFileMatcher: NSObject { } - (void) getFilesMatchingRegEx: (NSString *) inRegex forPath: (NSString *) inPath; @ end int main (int argc, const char * argv []) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // insérez du code ici ... MTFileMatcher * matcher = [[[[MTFileMatcher alloc] init] relecture automatique]; [Matcher getFilesMatchingRegEx: @ "^. + \\. [Jj] [Pp] [Ee]? E [Gg] $ "forPath: [@" ~/Pictures "stringByExpandingTildeInPath]]; [drain de piscine]; renvoyer 0; } @ implementation MTFileMatcher - (void) getFilesMatchingRegEx: (NSString *) inRegex pourPath: (NSString *) inPath; { NSArray * filesAtPath = [[NSFileManager defaultManager] directoryContentsAtPath: inPath] arrayByMatchingObjectsWithRegex: inRegex]; NSEnumerator * itr = [filesAtPath objectEnumerator]; NSString * obj; tant que (obj = [itr nextObject]) { NSLog (obj); } } @fin
Je ne prétends pas être un expert sur le sujet, mais vous devriez avoir accès à la fois à la fonction glob
et wordexp
de l'objectif-c, non?
stringWithFileSystemRepresentation ne semble pas être disponible sous iOS.