एक ग्लोब के साथ एक निर्देशिका में फ़ाइलों की सूची प्राप्त करना


136

किसी पागल कारण के लिए मैं किसी दिए गए निर्देशिका के लिए ग्लोब के साथ फ़ाइलों की सूची प्राप्त करने का एक तरीका नहीं खोज सकता।

मैं वर्तमान में कुछ के साथ फंस गया हूँ:

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

..और फिर वह सामान छीनना चाहता हूँ जो मैं नहीं चाहता। लेकिन जो मैं वास्तव में पसंद करता हूं वह पूरी निर्देशिका के लिए पूछने के बजाय "फू * .jpg" जैसी किसी चीज की खोज करने में सक्षम होना है, लेकिन मुझे ऐसा कुछ भी नहीं मिला है।

तो आप इसे कैसे करते हैं?


ब्रायन वेबस्टर के जवाब ने मुझे इसी तरह के मुद्दे में बहुत मदद की। 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
DirectoryContentsAtPath को iOS 2.0 से हटा दिया गया है। यह सवाल + जवाब बहुत पुराना है ...
जॉनी

7
बस आगे बढ़े और सामग्री का उपयोग करने के लिए कोड नमूने को अपडेट किया ।OfDirectoryAtPath: error: DirectoryContentsAtPath के बजाय:
ब्रायन वेबस्टर

5
हाँ, आप OR कथन का उपयोग करके अतिरिक्त तर्क जोड़ सकते हैं, जैसे "self ENDSWITH '.jpg' या आत्म ENDSWITH '.Png'"
ब्रायन वेबस्टर

2
यह भयानक है ... मैं एक पूरे दिन के लिए अन्य दृष्टिकोणों के साथ चारों ओर पेशाब कर रहा हूं! महान। मुख्य चाल बस यह जानना है कि स्टैको पर क्या खोजना है!
क्लिफ रिबोडो

3
आप "ENDSWITH" के बजाय "pathExtension == '.xxx' का उपयोग कर सकते हैं। इस उत्तर को देखें
ब्रूनो बेरीसो

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
एलेक्स Cio

इस प्रश्न का उत्तर देने के लिए सूची में यह पहली प्रतिक्रिया है, इसलिए मैंने इसे वोट किया
लड़के

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। यदि कोई टर्मिनल खोलता है तो टाइप करके ग्लोब के लिए एक मैन पेज खोलेंman 3 glob आप उन सभी जानकारियों को प्राप्त कर लेंगे जो आपको फंक्शन्स का उपयोग करने के लिए जानने की आवश्यकता है।

नीचे एक उदाहरण दिया गया है कि कैसे आप उन फ़ाइलों को पॉप्युलेट कर सकते हैं जो ग्लोबिंग पैटर्न से मेल खाती हैं। 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];

संपादित करें: मैंने github पर एक gist बनाया है जिसमें उपरोक्त कोड NSArray + Globbing नामक श्रेणी में है ।


stringWithCString:पदावनत किया गया है। सही प्रतिस्थापन है -[NSFileManager stringWithFileSystemRepresentation:length:], हालांकि मुझे लगता है कि अधिकांश लोग उपयोग करते हैं stringWithUTF8String:(जो कि आसान है लेकिन सही एन्कोडिंग होने की गारंटी नहीं है)।
पीटर होसी

5

आपको अपनी इच्छित फ़ाइलों को समाप्त करने के लिए अपनी स्वयं की विधि को रोल करने की आवश्यकता है।

यह बिल्ट इन टूल्स के साथ आसान नहीं है, लेकिन आप RegExKit Lite का उपयोग कर सकते हैं ताकि लौटे हुए सरणी में तत्वों को खोजने में सहायता कर सकें । वे रुचि रखते हैं। रिलीज़ नोटों के अनुसार यह कोको और कोको-टच दोनों अनुप्रयोगों में काम करना चाहिए।

यहाँ डेमो कोड मैंने लगभग 10 मिनट में लिखा था। मैंने <और> को बदल दिया क्योंकि वे प्री ब्लॉक के अंदर दिखाई नहीं दे रहे थे, लेकिन यह अभी भी उद्धरणों के साथ काम करता है। हो सकता है कि कोई व्यक्ति जो स्टैकऑवरफ़्लो पर कोड को फ़ॉर्मेट करने के बारे में अधिक जानता है, वह इसे (क्रिस?) सही करेगा।

यह एक "फाउंडेशन टूल" कमांड लाइन यूटिलिटी टेम्पलेट प्रोजेक्ट है। अगर मुझे अपना git डेमॉन मिलता है और अपने होम सर्वर पर चल रहा है तो मैं इस पोस्ट को प्रोजेक्ट के लिए URL जोड़ने के लिए संपादित करूँगा।

#import "फाउंडेशन / Foundation.h"
#import "RegexKit / RegexKit.h"

@interface MTFileMatcher: NSObject 
{
}
- (शून्य) getFilesMatchingRegEx: (NSString *) inRegex forPath: (NSString *) inPath;
@समाप्त

int main (int argc, const char * argv [])
{
    NSAutoreleasePool * पूल = [[NSAutoreleasePool आवंटित] init];

    // यहाँ कोड डालें ...
    MTFileMatcher * matcher = [[[MTFileMatcher आबंटित] init] autorelease];
    [matcher getFilesMatchingRegEx: @ "^ ^। + \\। [जज] [पीपी] [ईई] [जीजी] $" forPath: [@ "~ / चित्र" stringByExpandingTildeInPath]];

    [पूल नाली];
    वापसी 0;
}

@ कार्यान्वयन MTFileMatcher
- (शून्य) getFilesMatchingRegEx: (NSString *) inRegex forPath: (NSString *) inPath;
{
    NSArray * filesAtPath = [[[NSFileManager defaultManager] DirectoryContentsAtPath: inPath] arrayByMatchingObjectsWithRegex: inReetx];
    NSEnumerator * itr = [filesAtPath objectEnumerator];
    NSString * obj;
    जबकि (obj = [itr nextObject])
    {
        NSLog (obj);
    }
}
@समाप्त

3

मैं इस विषय पर एक विशेषज्ञ होने का दिखावा नहीं करूंगा, लेकिन आपको उद्देश्य-सी से कार्य globऔर wordexpकार्य दोनों की पहुंच होनी चाहिए , नहीं?



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  {  }
        }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.