2009-08-14 14 views
6

अभी मैं एक फ़ोल्डर का आकार प्राप्त करने के लिए इस कोड का उपयोग कर रहा हूँ:फ़ोल्डर का आकार पाने के लिए आसान तरीका (ओबीजेसी/कोको)?

NSArray *contents; 
     NSEnumerator *enumerator; 
     NSString *path; 
     contents = [[NSFileManager defaultManager] subpathsAtPath:folderPath]; 
     enumerator = [contents objectEnumerator]; 
     while (path = [enumerator nextObject]) { 
      NSDictionary *fattrib = [[NSFileManager defaultManager] fileAttributesAtPath:[folderPath stringByAppendingPathComponent:path] traverseLink:YES]; 
      fileSize +=[fattrib fileSize]; 
     } 

     [contents release]; 
     [path release]; 

समस्या यह है कि इसकी अत्यधिक innacurate है। यह या तो कुछ मेगाबाइट जोड़ता है या वास्तविक आकार से कुछ मेगाबाइट घटाता है। उदाहरण के लिए मुझे एक .app बंडल का फ़ाइल आकार मिला और इस विधि ने 16.2 एमबी की सूचना दी, जबकि वास्तविक चीज़ 15.8 है।

फ़ोल्डर का आकार प्राप्त करने का सबसे अच्छा तरीका क्या है?

धन्यवाद

+0

किसी सैंडबॉक्सिंग के तहत इस का उपयोग करते हुए? :-) –

उत्तर

5

मुझे आज यह करने की ज़रूरत है, और मुझे पता चला है कि this post on the Cocoa-dev list में कोड बहुत तेज़ है और यह पता चलता है कि फाइंडर बाइट को क्या कहता है। (करने के लिए या kFSCatInfoRsrcSizes ध्वज में तो तुम संसाधन कांटा आकार मिलता है, भी भूल जाते हैं नहीं!)

आप इसे उपयोग करने के लिए, बस एक टिप्पणी छोड़ दो और मैं इस पोस्ट को संपादित करेंगे के बारे में अधिक विवरण की जरूरत है। =)

+0

धन्यवाद, एनएसएसटींग को एक एफएसआरफ के पथ वाले रूपांतरित करने का एक अच्छा तरीका क्या है? धन्यवाद – indragie

+0

बस आपके प्रश्न का उत्तर दिया। =) –

+0

@ डेव, यह लिंक टूटा हुआ है, क्या आप इसे अपडेट कर सकते हैं या उत्तर देने के लिए कोड डाल सकते हैं? – Igor

1

यह आमतौर पर यह कैसे किया जाता है। 2 संभावनाएं:

  1. अपने बाइट -> मेगाबाइट रूपांतरण दिनचर्या की जांच करें। इसके अलावा, क्या आप मेगाबाइट्स या मेबिबाइट चाहते हैं? (यह संभव है कि आप इसे करने के लिए तुलना कर रहे हैं पर निर्भर करता है।)

  2. traverseLink पैरामीटर के लिए नहीं गुजर कोशिश करो। बंडल में एक सिम्लिंक बहुत अच्छी तरह से हो सकता है जो किसी और चीज को इंगित करता है कि जिस दिन आप इसकी तुलना कर रहे हैं, उसके लिए जिम्मेदार नहीं होगा। आप या तो दो बार बंडल में कुछ गिनेंगे, या आप पूरी तरह से बंडल के बाहर कुछ शामिल करेंगे (सबसे अधिक संभावना पूर्व)।

4

fileSize के लिए प्रलेखन में कहा गया है कि इसमें संसाधन कांटा का आकार शामिल नहीं है। निर्देशिका आकारों की भरोसेमंद गणना करने के लिए आपको Carbon File Manager API का उपयोग करने की आवश्यकता हो सकती है।

+0

आह हाँ, यह एक और संभावना है। मैं उसके बारे में भूल गया। – kperryua

2

मैं सिर्फ कोको-देव पर पोस्ट के बारे में डेव डीलॉन्ग के सुझाव को दूसरे स्थान पर लेना चाहता था, लेकिन धागे में सभी पदों को पढ़ने के लिए सावधानी बरतें। Rosyna द्वारा एक है जो विशेष रूप से ध्यान देने योग्य है। मेरे मामले में मैंने उस सलाह का पालन किया (प्रति प्राप्त अधिकतम वस्तुओं को 40 तक बदलना) और एक तेज कूद के साथ-साथ एक बुरा क्रैशिंग बग के अंत में देखा।

+1

इसे अपने उत्तर में टिप्पणी के रूप में जोड़ने के लिए बेहतर हो सकता है ताकि वे पृष्ठ परिवर्तन पर अपनी स्थिति के रूप में संबंधित रहें। –

+0

मुझे डेव डीलॉन्ग की विधि के साथ समस्याएं आ रही हैं। मैं अपने एनएसएसटींग को एक एफएसआरफ में बदलने के लिए इस कोड का उपयोग करता हूं: एफएसआरएफ एफ; \t \t ओएसएसटैटस os_status = FSPathMakeRef ((कॉन्स UInt8 *) [filePath फ़ाइल सिस्टमप्रणालीकरण], और एफ, न्यूल); \t \t यदि (os_status == noErr) { \t \t एनएसएलओजी (@ "सफलता"); \t \t} और फिर मैं विधि चलाने का प्रयास: [आत्म fastFolderSizeAtFSRef: च]; हालांकि मुझे त्रुटि मिलती है "फास्टफोल्डर आकार 'के तर्क 1 के लिए असंगत प्रकार" कोई विचार? धन्यवाद – indragie

2

मुझे पता है कि यह एक पुराना विषय है। लेकिन किसी के लिए वहाँ बाहर ऐसा करने के तरीके पर जवाब की तलाश में,

[[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir]; 
     if (isDir) { 
      NSPipe *pipe = [NSPipe pipe]; 
      NSTask *t = [[[NSTask alloc] init] autorelease]; 
      [t setLaunchPath:@"/usr/bin/du"]; 
      [t setArguments:[NSArray arrayWithObjects:@"-k", @"-d", @"0", path, nil]]; 
      [t setStandardOutput:pipe]; 
      [t setStandardError:[NSPipe pipe]]; 

      [t launch]; 

      [t waitUntilExit]; 

      NSString *sizeString = [[[NSString alloc] initWithData:[[pipe fileHandleForReading] availableData] encoding:NSASCIIStringEncoding] autorelease]; 
      sizeString = [[sizeString componentsSeparatedByString:@" "] objectAtIndex:0]; 
      bytes = [sizeString longLongValue]*1024; 
     } 
     else { 
      bytes = [[[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil] fileSize]; 
     } 

यह बाइट्स में फ़ोल्डर के लिए एक आकार निर्धारित करने के लिए टर्मिनल का उपयोग करेगा। और यह फ़ाइलों का आकार प्राप्त करने के लिए NSFileManager में कोको का निर्माण करेगा। यह बहुत तेज़ है, और सटीक आकार प्राप्त करता है जो खोजक रिपोर्ट करता है।

+0

जबकि यह निश्चित रूप से काम करेगा, आपके पास एक और प्रक्रिया (जो कि बहुत महंगा हो सकता है) बनाने का प्रदर्शन हिट है, या 'NSFileManager' का उपयोग करके, जिसमें आकारों की गणना करते समय संसाधन कांटा शामिल नहीं है। –

1

यह कोड NSFileManager क्लास के लिए एक्सटेंशन (श्रेणी) के रूप में है। यह सभी फ़ोल्डर सामग्री के आकार बताता है। ध्यान दें कि त्रुटि उपचार को बढ़ाया जा सकता है।

@interface NSFileManager(Util) 

     - (NSNumber *)sizeForFolderAtPath:(NSString *) source error:(NSError **)error; 

    @end 

    @implementation NSFileManager(Util) 

     - (NSNumber *)sizeForFolderAtPath:(NSString *) source error:(NSError **)error 
     { 
      NSArray * contents; 
      unsigned long long size = 0; 
      NSEnumerator * enumerator; 
      NSString * path; 
      BOOL isDirectory; 

      // Determine Paths to Add 
      if ([self fileExistsAtPath:source isDirectory:&isDirectory] && isDirectory) 
      { 
       contents = [self subpathsAtPath:source]; 
      } 
      else 
      { 
       contents = [NSArray array]; 
      } 
      // Add Size Of All Paths 
      enumerator = [contents objectEnumerator]; 
      while (path = [enumerator nextObject]) 
      { 
       NSDictionary * fattrs = [self attributesOfItemAtPath: [ source stringByAppendingPathComponent:path ] error:error]; 
       size += [[fattrs objectForKey:NSFileSize] unsignedLongLongValue]; 
      } 
      // Return Total Size in Bytes 

      return [ NSNumber numberWithUnsignedLongLong:size]; 
     } 

     @end 
0

आशा है कि यह मदद मिलेगी

- (unsigned long long) fastFolderSizeAtFSRef:(NSString *)theFilePath 
{ 
unsigned long long totalSize = 0; 
NSFileManager *fileManager = [NSFileManager defaultManager]; 
BOOL isdirectory; 
NSError *error; 

if ([fileManager fileExistsAtPath:theFilePath]) 
{ 


    NSMutableArray * directoryContents = [[fileManager contentsOfDirectoryAtPath:theFilePath error:&error] mutableCopy]; 


    for (NSString *fileName in directoryContents) 
    { 
     if (([fileName rangeOfString:@".DS_Store"].location != NSNotFound)) 
      continue; 



      NSString *path = [theFilePath stringByAppendingPathComponent:fileName]; 
      if([fileManager fileExistsAtPath:path isDirectory:&isdirectory] && isdirectory ) 
      { 

        totalSize = totalSize + [self fastFolderSizeAtFSRef:path]; 



      } 
      else 
      { 
       unsigned long long fileSize = [[fileManager attributesOfItemAtPath:path error:&error] fileSize]; 
       totalSize = totalSize + fileSize; 
      } 
    } 
} 
return totalSize; 
} 
संबंधित मुद्दे