Easy way to get folder size (ObjC / Cocoa)?

Now I use this code to get the size of the folder:

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

The problem is that he is very dishonest. It either adds a few megabytes or subtracts several megabytes from the actual size. For example, I got the size of the .app package file, and this method reported 16.2MB, while the actual thing is 15.8.

What is the best way to get folder size?

thanks

+6
objective-c folder cocoa size nsfilemanager
source share
7 answers

I needed to do this today myself, and I found that the code in this post on the Cocoa -dev list is very fast and matches what Finder says to the byte. (don’t forget the OR in the kFSCatInfoRsrcSizes flag so that you also get the dimensions of the resource fork!)

If you need more explanation on how to use it, just leave a comment and I will edit this post. =)

+5
source share

The documentation for fileSize states that it does not contain the size of the resource resource. You may need to use the Carbon File Manager API to reliably calculate directory sizes.

+4
source share

I just wanted to repeat Dave DeLong's suggestion for a Cocoa -dev write, but add a cautionary note to read all the messages in the stream. Especially worth noting Rosina. In my case, I followed this advice (changing the maximum values ​​to a sample of up to 40) and saw a speed jump, as well as the end of an unpleasant error.

+2
source share

I know this is an old topic. But for those there looking for answers on how to do this,

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

He will use the terminal to determine the size of folders in bytes. And he will use Cocoa built into NSFileManager to get file size. It is very fast and gets the exact size that the search query reports.

+2
source share

This is usually done. 2 possibilities:

  • Check byte conversion procedures β†’ megabytes. Also do you want megabytes or megabytes? (It probably depends on what you are comparing with.)

  • Try passing NO for the traverseLink parameter. There may be a symlink in the kit, indicating something else that the normal procedure with which you are comparing it will not be taken into account. You either count something in a bunch twice, or completely include something outside the package (most likely, the first).

+1
source share

This code is an extension (category) for the NSFileManager class. It summarizes the sizes of the entire contents of the folder. Please note that error handling can be improved.

  @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 
+1
source share

hope this helps

 - (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; } 
+1
source share

All Articles