Ottenere un elenco di file in una directory con un glob

Per qualche folle motivo non riesco a trovare un modo per ottenere un elenco di file con un glob per una determinata directory.

Sono attualmente bloccato con qualcosa sulla falsariga di:

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

..e poi togliere le cose che non voglio, che fa schifo. Ma quello che mi piacerebbe davvero è essere in grado di cercare qualcosa come “foo * .jpg” invece di chiedere l’intera directory, ma non sono stato in grado di trovare nulla di simile.

Quindi come diavolo lo fai?

Puoi farlo abbastanza facilmente con l’aiuto di NSPredicate, in questo modo:

 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]; 

Se hai bisogno di farlo con NSURL invece sembra che questo:

 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]; 

Questo funziona abbastanza bene per IOS , ma dovrebbe funzionare anche per il 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); } } 

Che ne dici di usare i metodi hasSuffix e hasPrefix di NSString? Qualcosa come (se stai cercando “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 } } 

Per partite semplici e semplici come quella sarebbe più semplice dell’uso di una libreria regex.

Metodo molto semplice:

 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 ha una libreria in grado di eseguire operazioni di globbing dei file per te. Le funzioni e i tipi sono dichiarati in un’intestazione chiamata glob.h , quindi dovrai #include . Se apri un terminale e apri la pagina man di glob digitando man 3 glob otterrai tutte le informazioni che devi sapere per utilizzare le funzioni.

Di seguito è riportato un esempio di come è ansible popolare un array per i file che corrispondono a un modello di globbing. Quando usi la funzione glob ci sono alcune cose che devi tenere a mente.

  1. Per impostazione predefinita, la funzione glob cerca i file nella directory di lavoro corrente. Per cercare in un’altra directory è necessario anteporre il nome della directory allo schema di globbing come ho fatto nel mio esempio per ottenere tutti i file in /bin .
  2. Sei responsabile della pulizia della memoria allocata da glob chiamando globfree quando hai finito con la struttura.

Nel mio esempio utilizzo le opzioni predefinite e nessun richiamo di errore. La pagina man copre tutte le opzioni nel caso in cui ci sia qualcosa che vuoi usare. Se hai intenzione di utilizzare il codice sopra, suggerirei di aggiungerlo come categoria a NSArray o qualcosa del genere.

 NSMutableArray* files = [NSMutableArray array]; glob_t gt; char* pattern = "/bin/*"; if (glob(pattern, 0, NULL, &gt) == 0) { int i; for (i=0; i 

Edit: ho creato un gist su github che contiene il codice sopra in una categoria chiamata NSArray + Globbing .

Devi eliminare il tuo metodo per eliminare i file che non vuoi.

Questo non è facile con gli strumenti integrati, ma è ansible utilizzare RegExKit Lite per aiutare a trovare gli elementi nell’array restituito a cui si è interessati. Secondo le note di rilascio, questo dovrebbe funzionare sia nelle applicazioni Cocoa che Cocoa-Touch.

Ecco il codice demo che ho scritto in circa 10 minuti. Ho cambiato in “perché non erano visibili nel pre-blocco, ma funziona ancora con le virgolette. Forse qualcuno che ne sa di più sulla formattazione del codice qui su StackOverflow correggerà questo (Chris?).

Questo è un progetto modello di utilità per riga di comando “Strumento di base”. Se riesco a far funzionare il mio demone git sul mio server di casa, modifico questo post per aggiungere l’URL per il progetto.

 #import "Foundation / Foundation.h"
 #import "RegexKit / RegexKit.h"

 @interface MTFileMatcher: NSObject 
 {
 }
 - (void) getFilesMatchingRegEx: (NSString *) inRegex forPath: (NSString *) inPath;
 @fine

 int main (int argc, const char * argv [])
 {
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

     // inserisci qui il codice ...
     MTFileMatcher * matcher = [[[MTFileMatcher alloc] init] autorelease];
     [matcher getFilesMatchingRegEx: @ "^. + \\. [Jj] [Pp] [Ee]? [Gg] $" forPath: [@ "~ / Pictures" stringByExpandingTildeInPath]];

     [scarico piscina];
     ritorno 0;
 }

 @implementation MTFileMatcher
 - (void) getFilesMatchingRegEx: (NSString *) inRegex forPath: (NSString *) inPath;
 {
     NSArray * filesAtPath = [[[NSFileManager defaultManager] directoryContentsAtPath: inPath] arrayByMatchingObjectsWithRegex: inRegex];
     NSEnumerator * itr = [filesAtPath objectEnumerator];
     NSString * obj;
     while (obj = [itr nextObject])
     {
         NSLog (obj);
     }
 }
 @fine

Non farò finta di essere un esperto sull’argomento, ma dovresti avere accesso sia alla funzione glob che wordexp funzione wordexp dell’objective-c, no?

stringWithFileSystemRepresentation non sembra disponibile in iOS.