获取具有glob的目录中的文件列表
由于一些疯狂的原因,我找不到一个方法来获得一个给定目录的glob文件列表。
我目前被困在一些方面:
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath]; NSArray *dirContents = [[NSFileManager defaultManager] directoryContentsAtPath:bundleRoot];
..然后剥离我不想要的东西,这很糟糕。 但是我真正喜欢的是能够search诸如“foo * .jpg”之类的东西,而不是要求整个目录,但是我一直没能find类似的东西。
那么你怎么做呢?
在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];
这对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); } }
那么使用NSString的hasSuffix和hasPrefix方法呢? 类似于(如果您正在search“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 } }
对于简单,直接的匹配,比使用正则expression式库更简单。
非常简单的方法:
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有一个可以为你执行文件通配操作的库。 函数和types在头文件glob.h中声明,所以你需要#include它。 如果打开一个terminal,通过inputman 3 glob打开glob的手册页,您将获得所有需要知道的使用这些function的信息。
下面是一个如何填充数组匹配符合条件的文件的例子。 当使用glob函数时,需要记住一些事情。
- 默认情况下,
glob函数在当前工作目录中查找文件。 为了search另一个目录,你需要在目录名前加上globbing模式,就像我在我的例子中所做的那样,将所有的文件都放在/bin。 - 当你完成这个结构时,你负责清理由
glob分配的内存。
在我的例子中,我使用默认选项,没有错误callback。 手册页涵盖了所有的选项,以防有些东西在你想要使用的地方。 如果你打算使用上面的代码,我会build议把它作为NSArray的类别或类似的东西。
NSMutableArray* files = [NSMutableArray array]; glob_t gt; char* pattern = "/bin/*"; if (glob(pattern, 0, NULL, >) == 0) { int i; for (i=0; i<gt.gl_matchc; i++) { [files addObject: [NSString stringWithCString: gt.gl_pathv[i]]]; } } globfree(>); return [NSArray arrayWithArray: files];
编辑:我已经在github上创build了一个包含上面的代码在一个名为NSArray + Globbing类别的要点 。
你需要推出你自己的方法来消除你不想要的文件。
使用内置的工具这并不容易,但是您可以使用RegExKit Lite来帮助查找您感兴趣的返回数组中的元素。根据发行说明,这可以在Cocoa和Cocoa-Touch应用程序中使用。
这是我在10分钟内写的演示代码。 我把<和>改成了“因为它们没有出现在前面块里面,但是仍然可以用引号进行操作。也许有人更熟悉StackOverflow的代码格式会纠正这个错误(Chris?)。
这是“基础工具”命令行实用程序模板项目。 如果我让我的git守护进程运行在我的主服务器上,我将编辑这个post来添加项目的URL。
#import“Foundation / Foundation.h”
#import“RegexKit / RegexKit.h”
@interface MTFileMatcher:NSObject
{
}
- (void)getFilesMatchingRegEx:(NSString *)inRegex forPath:(NSString *)inPath;
@结束
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]];
[pool drain];
返回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);
}
}
@结束
我不会假装成为这个主题的专家,但是你应该可以访问objective-c中的glob和wordexp函数,不是吗?
stringWithFileSystemRepresentation在iOS中似乎不可用。