Obtendo uma lista de arquivos em um diretório com um glob

Por algum motivo louco eu não consigo encontrar uma maneira de obter uma lista de arquivos com um glob para um determinado diretório.

Atualmente estou preso com algo ao longo das linhas de:

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

..e, em seguida, retirando as coisas que eu não quero, o que é uma merda. Mas o que eu realmente gosto é poder pesquisar por algo como “foo * .jpg” em vez de perguntar pelo diretório inteiro, mas não consegui encontrar nada parecido.

Então, como diabos você faz isso?

Você pode conseguir isso facilmente com a ajuda do NSPredicate, assim:

 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 você precisar fazer isso com a NSURL, será assim:

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

Isso funciona muito bem para o IOS , mas também deve funcionar para o 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); } } 

Que tal usar os methods hasSfixix e hasPrefix do NSString? Algo como (se você está procurando por “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 } } 

Para combinações simples e diretas como essa, seria mais simples do que usar uma biblioteca de regex.

Método muito mais simples:

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

O Unix tem uma biblioteca que pode executar operações de globalização de arquivos para você. As funções e tipos são declarados em um header chamado glob.h , então você precisará glob.h #include . Se abrir um terminal e abrir a página de manual para glob digitando man 3 glob você obterá todas as informações necessárias para usar as funções.

Abaixo está um exemplo de como você pode preencher uma matriz com os arquivos que correspondem a um padrão de globbing. Ao usar a function glob , há algumas coisas que você precisa ter em mente.

  1. Por padrão, a function glob procura por arquivos no diretório de trabalho atual. Para pesquisar em outro diretório, você precisará prefixar o nome do diretório para o padrão de globbing como eu fiz no meu exemplo para obter todos os arquivos em /bin .
  2. Você é responsável por limpar a memory alocada pelo glob chamando globfree quando tiver concluído a estrutura.

No meu exemplo, uso as opções padrão e nenhum retorno de chamada de erro. A página man abrange todas as opções, caso haja algo que você queira usar. Se você for usar o código acima, sugiro adicioná-lo como uma categoria ao NSArray ou algo parecido.

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

Edit: Eu criei uma essência no github que contém o código acima em uma categoria chamada NSArray + Globbing .

Você precisa aplicar seu próprio método para eliminar os arquivos que não deseja.

Isso não é fácil com as ferramentas integradas, mas você pode usar o RegExKit Lite para ajudar a encontrar os elementos da matriz retornada de seu interesse. De acordo com as notas de versão, isso deve funcionar nos aplicativos Cocoa e Cocoa-Touch.

Aqui está o código de demonstração que eu escrevi em cerca de 10 minutos. Eu mudei o para “porque eles não estavam aparecendo dentro do pré-bloco, mas ainda funciona com as aspas. Talvez alguém que saiba mais sobre formatação de código aqui no StackOverflow irá corrigir isso (Chris?).

Este é um projeto de modelo de utilitário de linha de comando “Ferramenta de base”. Se eu colocar meu daemon git em execução no meu servidor doméstico, eu editarei esta postagem para adicionar a URL do projeto.

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

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

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

     // insira o código aqui ...
     MTFileMatcher * matcher = [[[alocação de MTFileMatcher] init] autorelease];
     [matcher getFilesMatchingRegEx: @ "^. + \\. [Jj] [Pp] [Ee]? [Gg] $" forPath: [@ "~ / Imagens" stringByExpandingTildeInPath]];

     [dreno da piscina];
     return 0;
 }

 @implementation MTFileMatcher
 - (void) getFilesMatchingRegEx: (NSString *) inRegex paraPath: (NSString *) inPath;
 {
     NSArray * filesAtPath = [[[NSFileManager defaultManager] directoryContentsAtPath: inPath] arrayByMatchingObjectsWithRegex: inRegex];
     NSEnumerator * itr = [filesAtPath objectEnumerator];
     NSString * obj;
     while (obj = [itr próximoObjeto])
     {
         NSLog (obj);
     }
 }
 @fim

Não vou fingir ser um especialista no assunto, mas você deve ter access tanto à function glob quanto a wordexp do objective-c, não?

stringWithFileSystemRepresentation não parece estar disponível no iOS.