it-swarm.com.ru

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

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

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

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

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

Так как, черт возьми, ты это делаешь?

133
sammich

Вы можете достичь этого довольно легко с помощью 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];
238
Brian Webster

Это прекрасно работает для 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);            
    }       
}
32
Matt

Как насчет использования методов 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

    }
}

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

27
John Biesnecker

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

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);
12
Rajesh Loganathan

В 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 .

10
Bryan Kyle

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

Это не легко со встроенными инструментами, но вы можете использовать RegExKit Lite , чтобы помочь найти элементы в возвращаемом массиве, который вас интересует. Согласно примечаниям к выпуску, это должно работать как в Какао и приложения 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]; 
 
 // вставьте код здесь ... 
 MTFileMatcher * matcher = [[[MTFileMatcher alloc] init] autorelease]; 
 [Matcher getFilesMatchingRegEx: @ "^. + \\. [Jj] [Pp] [Ee]? [Gg] $ "forPath: [@" ~/Pictures "stringByExpandingTildeInPath]]; 
 
 [утечка пула]; 
 return 0; 
} 
 
 @ реализация 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); 
} 
}
@конец
5
Mark

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

3
Sean Bright

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

2
Oscar