2009-01-31 51 views
131

Vì một số lý do điên rồ, tôi không thể tìm cách để lấy danh sách các tập tin với một glob cho một thư mục nhất định.Lấy danh sách các tập tin trong một thư mục với một glob

tôi đang mắc kẹt với một cái gì đó dọc theo dòng:

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

..và sau đó tước ra những thứ tôi không muốn, mà sucks. Nhưng điều tôi thực sự thích là có thể tìm kiếm thứ gì đó như "foo * .jpg" thay vì yêu cầu toàn bộ thư mục, nhưng tôi không thể tìm thấy bất cứ thứ gì như thế.

Vậy bạn sẽ làm điều đó như thế nào?

+0

Brian Webster đã giúp tôi rất nhiều trong một vấn đề tương tự. http://stackoverflow.com/questions/5105250/run-nsbundle-from-the-documents-folder/7179584#7179584 – Wytchkraft

+1

Chỉ cần lưu ý bên cạnh cho bất kỳ ai đọc điều này, bạn có thể giải quyết vấn đề này bằng cách chỉ cần đưa tệp của mình vào thư mục http://stackoverflow.com/questions/1762836/create-a-folder-inside-documents-folder-in-ios-apps – seo

Trả lời

3

Tôi sẽ không giả vờ là chuyên gia về chủ đề này, nhưng bạn phải có quyền truy cập vào cả hai chức năng globwordexp từ mục tiêu-c, không?

5

Bạn cần phải cuộn phương pháp của riêng mình để loại bỏ các tệp bạn không muốn.

Điều này không dễ dàng với các công cụ tích hợp sẵn, nhưng bạn có thể sử dụng RegExKit Lite để hỗ trợ tìm kiếm các phần tử trong mảng được trả về mà bạn quan tâm. Theo ghi chú phát hành, điều này sẽ hoạt động ở cả Cocoa và Cocoa-Touch các ứng dụng.

Đây là mã demo tôi đã viết trong khoảng 10 phút. Tôi đã thay đổi < và> thành "vì chúng không hiển thị bên trong khối trước, nhưng nó vẫn hoạt động với dấu ngoặc kép. Có thể ai đó biết thêm về định dạng mã ở đây trên StackOverflow sẽ sửa lỗi này (Chris?).

This is a "Quỹ Tool" Command Line Tiện ích dự án mẫu. Nếu tôi nhận được git daemon của tôi và chạy trên máy chủ gia đình của tôi, tôi sẽ sửa bài này để thêm URL cho dự án.

 
#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 
27

gì về sử dụng phương thức hasSuffix và hasPrefix của NSString? Giống như (nếu bạn đang tìm kiếm "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 

    } 
} 

Đối với các kết quả đơn giản, đơn giản như vậy, nó sẽ đơn giản hơn việc sử dụng thư viện regex.

+0

Bạn nên sử dụng 'contentsOfDirectoryAtPath: error:' thay vì 'directoryContentsAtPath' vì' deprecated' của nó kể từ 'iOS' 2.0 –

+0

Đây là câu trả lời đầu tiên trong danh sách để trả lời câu hỏi, vì vậy tôi đã bỏ phiếu cho nó lên – Guy

236

Bạn có thể đạt được điều này khá dễ dàng với sự giúp đỡ của NSPredicate, như vậy:

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

Nếu bạn cần phải làm điều đó với NSURL thay vào đó nó trông như thế này:

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

directoryContentsAtPath không được dùng nữa kể từ iOS 2.0. Câu hỏi này + câu trả lời quá cũ ... – Jonny

+7

Chỉ cần tiếp tục và cập nhật mẫu mã để sử dụng contentOfDirectoryAtPath: error: chứ không phải là directoryContentsAtPath: –

+0

điều này sẽ rất tuyệt! có cách nào để định dạng vị từ để bắt hai loại tệp cùng một lúc, chẳng hạn như '.jpg' và '.png' không? – mtmurdock

10

Unix có một thư viện có thể thực hiện các hoạt động tập tin cho bạn. Các chức năng và loại được khai báo trong tiêu đề có tên là glob.h, vì vậy bạn cần phải #include nó. Nếu mở một thiết bị đầu cuối, hãy mở trang hướng dẫn sử dụng cho glob bằng cách nhập man 3 glob bạn sẽ nhận được tất cả thông tin bạn cần biết để sử dụng các chức năng.

Dưới đây là ví dụ về cách bạn có thể điền một mảng các tệp khớp với mẫu hình cầu. Khi sử dụng chức năng glob, có một vài điều bạn cần lưu ý.

  1. Theo mặc định, chức năng glob tìm kiếm tệp trong thư mục làm việc hiện tại.Để tìm kiếm một thư mục khác, bạn cần phải thêm tên thư mục vào mẫu globbing như tôi đã làm trong ví dụ của mình để lấy tất cả các tệp trong /bin.
  2. Bạn chịu trách nhiệm làm sạch bộ nhớ được phân bổ bởi glob bằng cách gọi globfree khi bạn hoàn tất cấu trúc.

Trong ví dụ của tôi, tôi sử dụng tùy chọn mặc định và không có lỗi gọi lại. Trang người đàn ông bao gồm tất cả các tùy chọn trong trường hợp có điều gì đó trong đó bạn muốn sử dụng. Nếu bạn định sử dụng mã ở trên, tôi khuyên bạn nên thêm mã đó làm danh mục cho NSArray hoặc một thứ như thế.

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

Chỉnh sửa: Tôi đã tạo một ý chính về github có chứa mã ở trên trong danh mục được gọi là NSArray+Globbing.

+0

'stringWithCString:' không được chấp nhận. Sự thay thế đúng là '- [NSFileManager stringWithFileSystemRepresentation: length:]', mặc dù tôi nghĩ hầu hết mọi người sử dụng 'stringWithUTF8String:' (dễ dàng hơn nhưng không được bảo đảm là mã hóa đúng). –

+0

@Peter Cảm ơn gợi ý. –

2

stringWithFileSystemRepresentation dường như không có sẵn trong iOS.

32

Điều này hoạt động khá độc đáo đối với IOS, nhưng cũng phải hoạt động cho 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);    
    }  
} 
12

Phương Rất đơn giản: Câu trả lời

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); 
Các vấn đề liên quan