Получение списка файлов в каталоге с глобусом - PullRequest
133 голосов
/ 01 февраля 2009

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

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

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

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

Так какого чёрта ты это делаешь?

Ответы [ 8 ]

238 голосов
/ 25 мая 2009

Вы можете достичь этого довольно легко с помощью 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];
32 голосов
/ 07 апреля 2011

Это прекрасно работает для 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);            
    }       
}
27 голосов
/ 25 мая 2009

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

    }
}

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

12 голосов
/ 14 ноября 2013

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

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);
10 голосов
/ 03 февраля 2010

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

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

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

В моем примере я использую параметры по умолчанию и не возвращаю сообщение об ошибке. Страница man охватывает все опции на случай, если там есть что-то, что вы хотите использовать. Если вы собираетесь использовать приведенный выше код, я бы предложил добавить его в качестве категории к 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];

Редактировать: я создал Gist на GitHub, который содержит вышеуказанный код в категории NSArray + Globbing .

5 голосов
/ 03 февраля 2009

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

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

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

Это шаблонный проект утилиты командной строки "Foundation Tool". Если я запустил мой 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
3 голосов
/ 01 февраля 2009

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

2 голосов
/ 26 октября 2010

stringWithFileSystemRepresentation недоступно в iOS.

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