Получение списка файлов в каталоге с глобусом

По какой-то сумасшедшей причине я не могу найти способ получить список файлов с глобусом для данного каталога.

В настоящее время я застрял в чем-то рядом:

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

.. а затем вырезать вещи, которые я не хочу, что отстой. Но мне бы очень хотелось, чтобы вы могли искать что-то вроде "foo *.jpg" вместо запроса всего каталога, но я не смог найти ничего подобного.

Итак, как вы это делаете?

Ответ 1

Вы можете добиться этого довольно легко с помощью NSPredicate, например:

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

Если вам нужно сделать это с помощью NSURL, это будет выглядеть так:

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

Это хорошо работает для IOS, но также должно работать для 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);            
    }       
}

Ответ 3

Как насчет использования методов NSString hasSuffix и hasPrefix? Что-то вроде (если вы ищете "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

    }
}

Для простых, простых совпадений это будет проще, чем использование библиотеки регулярных выражений.

Ответ 4

Очень простой метод:

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

Ответ 5

В Unix есть библиотека, которая может выполнять операции с файлами. Функции и типы объявляются в заголовке glob.h, поэтому вам нужно #include его. Если открыть терминал, откройте страницу man для glob, набрав man 3 glob, вы получите всю информацию, которую вам нужно знать, чтобы использовать функции.

Ниже приведен пример того, как вы можете заполнить массив файлами, которые соответствуют шаблону globbing. При использовании функции glob есть несколько вещей, которые вам нужно иметь в виду.

  • По умолчанию функция glob ищет файлы в текущем рабочем каталоге. Чтобы выполнить поиск в другом каталоге, вам нужно добавить имя каталога к шаблону globbing, как я сделал в моем примере, чтобы получить все файлы в /bin.
  • Вы отвечаете за очистку памяти, выделенной glob, вызывая globfree, когда вы закончите со структурой.

В моем примере я использую параметры по умолчанию и нет обратного вызова ошибки. Страница руководства охватывает все варианты, если вы там что-то хотите использовать. Если вы собираетесь использовать приведенный выше код, я бы предложил добавить его как категорию в NSArray или что-то в этом роде.

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

Изменить: я создал gistub, содержащий вышеуказанный код в категории NSArray + Globbing.

Ответ 6

Вам нужно перевернуть свой собственный метод, чтобы исключить файлы, которые вам не нужны.

Это непросто со встроенными инструментами, но вы можете использовать RegExKit Lite, чтобы помочь найти элементы в возвращаемом массиве, которые вы В соответствии с примечаниями к выпуску это должно работать как в приложениях Cocoa, так и Cocoa -Touch.

Вот демо-код, который я написал за 10 минут. Я изменил < и > to ", потому что они не появлялись внутри предварительного блока, но все равно работают с кавычками. Может быть, кто-то, кто знает больше о форматировании кода здесь, в StackOverflow, исправит это (Chris?).

Это шаблонный проект "Утилита командной строки". Если я верну свой демон git на моем домашнем сервере, я отредактирую этот пост, чтобы добавить URL-адрес проекта.

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

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

    [pool drain];
    return 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);
    }
}
@end

Ответ 7

Я не буду притворяться экспертом по этой теме, но у вас должен быть доступ к функциям glob и wordexp из objective-c, no?

Ответ 8

stringWithFileSystemRepresentation не представляется доступным в iOS.