glob가있는 디렉토리에서 파일 목록 가져 오기


136

미친 이유 때문에 주어진 디렉토리에 대한 glob가있는 파일 목록을 얻는 방법을 찾을 수 없습니다.

나는 현재 다음과 같은 라인에 무언가 붙어있다.

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

.. 그리고 내가 원하지 않는 것들을 벗겨 낸다. 그러나 내가 정말로 원하는 것은 전체 디렉토리를 요구하는 대신 "foo * .jpg"와 같은 것을 검색하는 것이지만, 그런 것을 찾을 수 없었습니다.

도대체 어떻게 그렇게합니까?


Brian Webster의 답변이 비슷한 문제에서 많은 도움이되었습니다. stackoverflow.com/questions/5105250/…
Wytchkraft

1
이 글을 읽는 사람에게만 참고하면, 파일을 폴더에 넣음으로써이 문제를 해결할 수 있습니다. stackoverflow.com/questions/1762836/…
seo

답변:


240

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 2.0부터 directoryContentsAtPath가 사용되지 않습니다. 이 질문과 답변이 너무 오래되었습니다 ...
Jonny

7
그냥 나서서 contentsOfDirectoryAtPath를 사용하는 코드 예제를 업데이트 : 오류 : 오히려 directoryContentsAtPath 이상 :
브라이언 웹스터

5
예, "self ENDSWITH '.jpg'또는 self ENDSWITH '.png'"와 같은 OR 문을 사용하여 논리를 추가 할 수 있습니다.
Brian Webster

2
이것은 굉장합니다 ... 나는 하루 종일 다른 접근법으로 소변을 보았습니다! 큰. 주요 요령은 StackO에서 무엇을 검색해야 하는지를 아는 것입니다!
Cliff Ribaudo

3
"ENDSWITH"대신 "pathExtension == '.xxx'"를 사용할 수 있습니다. 이 답변을
브루노 Berisso

34

이것은 꽤 잘 작동 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);            
    }       
}

28

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

    }
}

간단하고 직접적인 일치는 정규 표현식 라이브러리를 사용하는 것보다 간단합니다.


당신은 사용해야합니다 contentsOfDirectoryAtPath:error:대신 directoryContentsAtPath때문에 deprecated이후 iOS2.0
알렉스 C10의

이것은 목록에서 질문에 대한 첫 번째 답변이므로 투표했습니다.
Guy

12

가장 간단한 방법 :

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

유닉스에는 파일 글 로빙 작업을 수행 할 수있는 라이브러리가 있습니다. 함수와 타입은이라는 헤더에 선언되어 glob.h있어야 #include합니다. 터미널을 열면 다음을 입력하여 glob에 대한 맨 페이지를 엽니 다.man 3 glob 기능을 사용하는 데 필요한 모든 정보를 얻을 수 있습니다.

아래는 globbing 패턴과 일치하는 파일을 배열에 채울 수있는 방법의 예입니다. 이 glob기능을 사용할 때 명심해야 할 것이 몇 가지 있습니다.

  1. 기본적 glob으로이 기능은 현재 작업 디렉토리에서 파일을 찾습니다. 다른 디렉토리를 검색하려면 내 파일에서 모든 파일을 가져 오기 위해 수행 한 것처럼 디렉토리 이름을 글 로빙 패턴 앞에 추가해야합니다 /bin.
  2. 구조가 끝나면 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];

편집 : NSArray + Globbing 이라는 범주에 위 코드를 포함하는 github에 요점을 만들었습니다 .


stringWithCString:더 이상 사용되지 않습니다. -[NSFileManager stringWithFileSystemRepresentation:length:]대부분의 사람들이 사용한다고 생각하지만 올바른 대체는 stringWithUTF8String:입니다 (더 쉽지만 올바른 인코딩이라고 보장하지는 않습니다).
Peter Hosey 2019

5

원하지 않는 파일을 제거하려면 고유 한 방법을 사용해야합니다.

내장 도구로는 쉽지 않지만 RegExKit Lite 를 사용 하여 관심있는 반환 배열의 요소를 찾는 데 도움을 줄 수 있습니다 . 릴리스 정보에 따르면 Cocoa 및 Cocoa-Touch 응용 프로그램 모두에서 작동합니다.

약 10 분 안에 작성한 데모 코드가 있습니다. <와>을 사전 블록 안에 표시되지 않았기 때문에 "로 변경했지만 여전히 따옴표로 작동합니다. StackOverflow에서 코드 형식에 대해 더 알고있는 누군가가이 문제를 해결할 것입니다 (Chris?).

이것은 "Foundation Tool"명령 행 유틸리티 템플릿 프로젝트입니다. git 데몬을 시작하고 홈 서버에서 실행하면이 게시물을 편집하여 프로젝트의 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 * 풀 = [[NSAutoreleasePool alloc] init];

    // 여기에 코드를 삽입하십시오 ...
    MTFileMatcher * 매처 = [[[MTFileMatcher alloc] init] 자동 릴리스];
    [matcher getFilesMatchingRegEx : @ "^. + \\. [Jj] [Pp] [Ee]? [Gg] $"forPath : [@ "~ / Pictures stringByExpandingTildeInPath]];

    [풀 배수구];
    리턴 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);
    }
}
@종료

3

나는 그 주제에 대해 전문가 인 척하지는 않지만 objective-c의 기능 globwordexp기능 에 모두 액세스 할 수 있어야합니다 .


2

iOS에서는 stringWithFileSystemRepresentation을 사용할 수없는 것으로 보입니다.


0

스위프트 5

이것은 코코아에 효과적입니다.

        let bundleRoot = Bundle.main.bundlePath
        let manager = FileManager.default
        let dirEnum = manager.enumerator(atPath: bundleRoot)


        while let filename = dirEnum?.nextObject() as? String {
            if filename.hasSuffix(".data"){
                print("Files in resource folder: \(filename)")
            }
        }

0

코코아 용 스위프트 5

        // Getting the Contents of a Directory in a Single Batch Operation

        let bundleRoot = Bundle.main.bundlePath
        let url = URL(string: bundleRoot)
        let properties: [URLResourceKey] = [ URLResourceKey.localizedNameKey, URLResourceKey.creationDateKey, URLResourceKey.localizedTypeDescriptionKey]
        if let src = url{
            do {
                let paths = try FileManager.default.contentsOfDirectory(at: src, includingPropertiesForKeys: properties, options: [])

                for p in paths {
                     if p.hasSuffix(".data"){
                           print("File Path is: \(p)")
                     }
                }

            } catch  {  }
        }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.